看都没有人写树状数组
自己就写了一个
只是想完善一下这道题的解法
有些能用线段做的题就可以用树状数组做
本题也是可以的
但是建立树状数组的时候需要优化
不能无脑的while(x<1000001)
不然第5个点要T
另外还要有一个小特判
总之这道题树状数组并不是最优的解法
但树状数组也能做
ps:裸的树状数组87分(自己优化了 交了4次才A)
#include <iostream>
#include <cstdio>
using namespace std;
int n,a[1000001],l[5001],r[5001],maxn=0,minn=2000000,flag,ha,dha,q,w,sl,sr;
int lowbit(int x){return x&(-x);}
int min(int aa,int bb){if (aa<bb) return aa;return bb;}
int max(int aa,int bb){if (aa>bb) return aa;return bb;}
void add(int x,int k)
{
while (x<=maxn+1) //如果按下面的特判写的话,这里不优化可能也能A(不优化的话写成x<=1000001)
{
a[x]+=k;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=0;
while (x>=minn)
{
sum+=a[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&l[i],&r[i]);
if (l[i]<minn && r[i]>maxn) {sl=l[i]; sr=r[i];} //特判有那么一次 从开始挤到结束
maxn=max(maxn,r[i]); minn=min(minn,l[i]);
}
if (sl==minn && sr==maxn) {ha=maxn-minn; dha=0;} //特判
else
{
for (int i=1;i<=n;i++)
{
add(l[i],1); add(r[i]+1,-1); //注意建树状数组的位置,若在外面建的话 特判就白写了
}
for (int i=minn;i<=maxn;i++)
{
if (query(i)>0)
{
q++; while (query(i+1)>0) {q++; i++;}
ha=max(ha,q-1); q=0;
}
else if (!query(i))
{
w++; while (!query(i+1)) {w++; i++;}
dha=max(dha,w+1); w=0;
}
}
}
printf("%d %d",ha,dha);
return 0;
}