Luogu3028 solution
Problem
给定 \(n\) 个区间 \([l_i,r_i]\),找到一个点,使之包含它的区间最多。
link->https://www.luogu.com.cn/problem/P3028
Solution
我们将题目换一种方法来理解:给定 \(n\) 个区间 \([l_i,r_i]\) 将其中的每个元素都给 \(+1\),求问最后的所有元素最大值。
是的,聪明的你一下子就看了出来,这是一道裸的差分。
for(int i=1;i<=n;i++) {
int l,r;
scanf("%d%d",&l,&r);
d[l]++; d[r+1]--;
}
但...这样就完了吗?不,我们看见 \(l_i,r_i\le10^9\),数组无疑存不下这么大的空间,就算存的下,我们将 \(0\) 至 \(\max\{r_i\}\) 一一遍历仍会超时。
这是,我们需要使用一种方法叫做离散化,这里不作过多介绍。
Code
#include<bits/stdc++.h>
#define pd push_back
#define pb pop_back
#define mk make_pair
//#define int long long
#define PII pair<int,int>
#define _for(a,b,c) for(int a=b;a<=c;a++)
#define _rep(a,b,c) for(int a=b;a>=c;a--)
using namespace std;
template <typename T> inline void read(T& x) {
x=0; T f=1;
char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch&15); ch=getchar(); }
x=x*f;
return;
}
template <typename T,typename ...Arg> inline void read(T& x,Arg& ...arg){
read(x); read(arg...);
}
int power(int a,int b) {
int ans=1;
do {
if(b&1) ans*=a; a*=a;
} while(b>>=1);
return ans;
}
const int N=1e5+5;
int d[N],l[N],r[N],v[N],tot,n,ans;
signed main() {
read(n);
_for(i,1,n)
read(l[i],r[i]),v[++tot]=l[i],v[++tot]=r[i];
sort(v+1,v+tot+1); //排序
tot=unique(v+1,v+tot+1)-(v+1); //去重
_for(i,1,n) {
// printf("(%d,%d)+=1\n",lower_bound(v+1,v+tot+1,l[i])-v,lower_bound(v+1,v+tot+1,r[i])-v);
++d[lower_bound(v+1,v+tot+1,l[i])-v],--d[lower_bound(v+1,v+tot+1,r[i])-v+1]; //将离散化后的 l[i]~r[i] 区间+1
}
_for(i,1,tot+1)
ans=max(ans,d[i]+=d[i-1]); //做前缀和,还原数组
printf("%d",ans);
return 1;
}

浙公网安备 33010602011771号