题意:那个城市里要竞选市长,然后在一块墙上可以贴海报为自己拉票,每个人可以贴连续的一块区域,后来帖的可以覆盖前面的,问到最后一共可以看到多少张海报。
思路:一看就知道是线段树,只是说要利用到离散化,也不是那么的难,当然注意,有的离散化错误也ac了......当然,在最后没必要还一个个去询问是否覆盖,直接开个标记数组,询问到一个区间只有一个覆盖值,然后进行标记就可以。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define M 100005 struct node { int ll,rr; int num; int cnt; }tree[8*M]; int s[4*M][2],t[4*M]; int xx[4*M]; int ans=0,flag=0; void creat(int i,int l,int r) { tree[i].ll=l; tree[i].rr=r; tree[i].cnt=0; tree[i].num=0; int mid=(l+r)/2; if(l==r) { //tree[i].num=0; return; } creat(i*2,l,mid); creat(i*2+1,mid+1,r); } void updata(int i,int left,int right,int k) { if(tree[i].ll==left&&tree[i].rr==right) { tree[i].cnt=1; tree[i].num=k; //if(k==2) //printf("%d %d ",left,right); return; } if(tree[i].cnt==1) { tree[i*2].cnt=1; tree[i*2+1].cnt=1; tree[i*2].num=tree[i].num; tree[i*2+1].num=tree[i].num; tree[i].cnt=2; tree[i].num=0; } int mid=(tree[i].ll+tree[i].rr)/2; if(mid>=right) updata(i*2,left,right,k); else if(mid<left) updata(i*2+1,left,right,k); else { updata(i*2,left,mid,k); updata(i*2+1,mid+1,right,k); } if(tree[i*2].cnt==1&&tree[i*2+1].cnt==1&&tree[i*2].num==tree[i*2+1].num) { tree[i].cnt=1; tree[i].num=tree[i*2].num; } else tree[i].cnt=2; //printf("updata "); } void quest(int i) { //if(k==1) //printf("%d %d %d %d %d ",tree[i].ll,tree[i].rr,tree[i].cnt,tree[i].num,k); if(tree[i].cnt==1) { xx[tree[i].num]=1; return; } if(tree[i].ll==tree[i].rr) return; //if(flag==1) //return; if(tree[i].cnt==0) return; quest(i*2); quest(i*2+1); // printf("quest "); } int erfen(int ll,int rr,int num) { while(ll<=rr) { int mid=(ll+rr)/2; if(t[mid]>num) rr=mid-1; else ll=mid+1; // printf("erfen "); } return rr; } int main() { int text; scanf("%d",&text); while(text--) { int n; scanf("%d",&n); //creat(1,1,3*n); int cnt=0; for(int i=0;i<n;i++) { scanf("%d%d",&s[i][0],&s[i][1]); t[cnt++]=s[i][0]; t[cnt++]=s[i][1]; } sort(t,t+cnt); int cnt1=1; for(int i=1;i<cnt;i++) if(t[i]!=t[i-1]) t[cnt1++]=t[i]; for(int i=cnt1-1;i>0;i--) if(t[i]!=t[i-1]+1) t[cnt1++]=t[i-1]+1; sort(t,t+cnt1); for(int i=cnt1;i>0;i--) t[i]=t[i-1]; creat(1,1,cnt1+5); for(int i=1;i<=n;i++) { int ll=1,rr=cnt1; int tmp=erfen(ll,rr,s[i-1][0]); int tmp1=erfen(ll,rr,s[i-1][1]); //tmp; //tmp1; //printf("%d %d ",tmp,tmp1); updata(1,tmp,tmp1,i); } ans=0; memset(xx,0,sizeof(xx)); quest(1); for(int i=1;i<=n;i++) if(xx[i]==1) ans++; printf("%d ",ans); } return 0; }