POJ 2528 Mayor's Posters

    技术2022-05-20  56

    不难发现,问你有几张海报可见,其实就是问你最后[1,ri]这个区间上被染上了几种颜色

     

    但问题是,ri很大,建这么大的树显然会超时,不过还好,n不是很大,我们可以用离散化的思想来解决

     

    把所有出现的坐标点进行排序,去重,这样,线段树的总长就不会超过2W了,然后把原来每张海报的坐标找到新的对应点,以新的对应点进行区间染色,最后统计一下有几种颜色即可

     

    代码:

    #include<iostream> #include<memory.h> #include<string> #include<cstdio> #include<algorithm> #include<math.h> #include<stack> #include<queue> using namespace std; const int MAX=20005; struct node { int l,r; int color; }t[MAX*5]; int pos[MAX][2],index[MAX*2]; int n,m; bool hash[10001]; void build(int ll,int rr,int n) { t[n].l=ll; t[n].r=rr; if(ll==rr) { t[n].color=0; return; } int mid=(ll+rr)/2; build(ll,mid,n*2); build(mid+1,rr,n*2+1); t[n].color=0; } int find(int x) { int l=0,r=m,mid,ans; //cout<<r<<endl; while(l<=r) { mid=(l+r)/2; if(index[mid]==x) { return mid+1; } if(index[mid]<x) l=mid+1; else r=mid-1; } } void update(int ll,int rr,int n,int c) { //cout<<"n="<<n<<endl; if(t[n].l==ll&&t[n].r==rr) { t[n].color=c; return; } if(t[n].color!=-1) t[n*2].color=t[n*2+1].color=t[n].color; t[n].color=-1; int mid=(t[n].l+t[n].r)/2; if(mid>=rr) update(ll,rr,n*2,c); else if(mid<ll) update(ll,rr,n*2+1,c); else { update(ll,mid,n*2,c); update(mid+1,rr,n*2+1,c); } } void query(int ll,int rr,int n) { if(t[n].l==ll&&t[n].r==rr&&t[n].color!=-1) { hash[t[n].color]=true; return; } int mid=(t[n].l+t[n].r)/2; if(mid>=rr) query(ll,rr,n*2); else if(mid<ll) query(ll,rr,n*2+1); else { query(ll,mid,n*2); query(mid+1,rr,n*2+1); } } int main() { int i,j,k,T; scanf("%d",&T); while(T--) { memset(hash,0,sizeof(hash)); scanf("%d",&n); for(k=0;k<n;k++) { scanf("%d%d",&pos[k][0],&pos[k][1]); index[k]=pos[k][0]; index[k+n]=pos[k][1]; } sort(index,index+n*2); for(i=0,m=0;i<n*2;i++) { if(i==0||index[i]!=index[i-1]) { index[m++]=index[i]; } } build(1,m,1); //cout<<t[4].l<<endl; for(k=0;k<n;k++) { i=find(pos[k][0]); j=find(pos[k][1]); update(i,j,1,k+1); } //cout<<"yes"<<endl; query(1,m,1); int ans=0; for(i=1;i<=n;i++) if(hash[i]) ans++; printf("%d/n",ans); } return 0; } 


    最新回复(0)