题意翻译
为了满足fj所有的N(1<=n<=50000)头奶牛的需求,fj新买了一台汽水机。他想找到一个最完美的位置来安放它。
奶牛的牧场可以被表示为一个一维数轴,第i个奶牛被放牧的区间是[Ai...Bi](包含端点),fj可以把汽水机放在[1..1,000,000,000]。
因为奶牛们都懒得要死,她们想尽可能的少移动。她们希望汽水机被放在自己的放牧区间内。
遗憾的是,fj并不总能满足所有奶牛的要求,所以他想请你帮忙算出他能满足的奶牛数目
输入
4 3 5 4 8 1 2 5 10
输出
3
根据观察,可以发现区间都非常大达到10^9如果直接暴力是O(10^9n)肯定会超时,所以我采用了离散化,将区间离散
这样可以把最大时间复杂度降低到O(n^2)
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,f=0;char s=getchar();
while(!isdigit(s))f|=s=='-',s=getchar();
while( isdigit(s))x=(x<<1)+(x<<3)+s-48,s=getchar();
return f==0?x:-x;
}
const int N=5e4+10;
struct LSnode{
int x,z,p;
inline bool operator<(const LSnode &k)const{
return x<k.x;
}
}b[N<<1];int a[N<<1];
int n;
int sum[N<<1];
int main(){
n=read();
for(int i=1;i<=n;i++){
b[2*i-1].x=read();
b[2*i ].x=read();
b[2*i-1].p=2*i-1;
b[2*i ].p=2*i;
}
sort(b+1,b+2*n+1);
b[1].z=1;
for(int i=2;i<=(n<<1);i++){
if(b[i].x==b[i-1].x)b[i].z=b[i-1].z;
else b[i].z=b[i-1].z+1;
}
for(int i=1;i<=(n<<1);i++)a[b[i].p]=b[i].z;
int maxx=0;
for(int i=1;i<=n;i++){
for(int j=a[2*i-1];j<=a[2*i];j++)
sum[j]++,maxx=max(maxx,sum[j]);
}
printf("%d\n",maxx);
return 0;
}
但是这个时间复杂度是O(n^2)还是会超时两个点,所以我想可以在区间修改时优化一下
因为上面的代码每次修改都是要从左到右每一个点都+1,所以我们可以考虑用前缀和的方式优化,因此只需要在每个区间的其实点+1,在区间的结束点+1的位置上-1,统计时不断的加这个点的sum值就好了
AC代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,f=0;char s=getchar();
while(!isdigit(s))f|=s=='-',s=getchar();
while( isdigit(s))x=(x<<1)+(x<<3)+s-48,s=getchar();
return f==0?x:-x;
}
const int N=5e4+10;
struct LSnode{
int x,z,p;
inline bool operator<(const LSnode &k)const{
return x<k.x;
}
}b[N<<1];int a[N<<1];
int n;
int sum[N<<1];
int main(){
n=read();
for(int i=1;i<=n;i++){
b[2*i-1].x=read();
b[2*i ].x=read();
b[2*i-1].p=2*i-1;
b[2*i ].p=2*i;
}
sort(b+1,b+2*n+1);
b[1].z=1;
for(int i=2;i<=(n<<1);i++){
if(b[i].x==b[i-1].x)b[i].z=b[i-1].z;
else b[i].z=b[i-1].z+1;
}
for(int i=1;i<=(n<<1);i++)a[b[i].p]=b[i].z;
int maxx=0;
for(int i=1;i<=n;i++){
sum[a[2*i-1]]++;
sum[a[2*i]+1]--;
}
int s=0;
for(int i=1;i<=b[n<<1].z;i++)s+=sum[i],maxx=max(maxx,s);
printf("%d\n",maxx);
return 0;
}