这道线段树题目应该对我离散化数据的思想有了启蒙,直接做必然超时超内存,所以根据虽然l,r范围好大,但给的海报数n<10000比较小,把l,r20000个数据对应到1-20000就压缩了空间,907msAC。
#include<cstdio>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
map<int,int>mp;
set<int>st;
int cmp(int a,int b)
{
return a<b;
}
int a[80010],c[80010],x[10010],y[10010];
void down(int i)
{
if(c[i])
{
c[2*i]=c[2*i+1]=c[i];
c[i]=0;
}
}
void build(int i,int l,int r)
{
c[i]=0;
if(l==r)
return;
int m=(l+r)>>1;
build(2*i,l,m);
build(2*i+1,m+1,r);
}
void ud(int i,int l,int r,int L,int R,int x)
{
if(l==L&&r==R)
{
c[i]=x;
return;
}
down(i);
int mid=(L+R)>>1;
if(mid>=r)
ud(2*i,l,r,L,mid,x);
else if(mid<l)
ud(2*i+1,l,r,mid+1,R,x);
else
{
ud(2*i,l,mid,L,mid,x);
ud(2*i+1,mid+1,r,mid+1,R,x);
}
}
void dfs(int i,int l,int r)
{
if(c[i])
{
st.insert(c[i]);
return;
}
if(l==r)
return;
int m=(l+r)>>1;
dfs(2*i,l,m);
dfs(2*i+1,m+1,r);
}
int t,n;
int main()
{
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
mp.clear();
st.clear();
int j=0;
for(int i=1;i<=n;i++)
{
int q,w;
scanf("%d%d",&q,&w);
x[i]=q,y[i]=w;
a[++j]=q;
a[++j]=w;
}
sort(a+1,a+2*n+1,cmp);
int z=0;
for(int i=1;i<=2*n;i++)
{
while(i!=2*n&&a[i]==a[i+1])i++;
mp[a[i]]=++z;
}
build(1,1,z);
for(int i=1;i<=n;i++)
{
ud(1,mp[x[i]],mp[y[i]],1,z,i);
}
dfs(1,1,z);
printf("%d\n",st.size());
}
return 0;
}