PKU 2528 Mayor's posters

    技术2024-07-23  16

    本题poster的宽度很大,而poster的数量很小。

     

    所以,离散化,保证不会TLE。

     

    离散完之后最多有20000个点。所以树的结构数组要开80000。

     

    一开始,由于只会建区间树,导致很多细节处理的不清楚,百度了别人代码,发现不太容易懂。

     

    最后,学了下怎么建立点树。然后,果断A了。

     

    //呜呜,不会点树的悲剧,做了3个小时,还好思路都对,算是一种安慰吧。。 //表示,有代码中的离散,看不懂 +_+ //O(∩_∩)O哈哈~ #include <iostream> #include <algorithm> #define MAX 90000 using namespace std; struct node{ int l,r,mid,cov; }tree[MAX];//线段树,请注意应该开4倍。 struct post{ int l,r; }po[10010];//输入数据 int s[20020],ls[20020];//s是一开始的坐标,ls是离散后的。 bool flag[10010]; void build(int l,int r,int num)//建立的是点树,即最小的区间表示[i,i]。 { tree[num].l=l; tree[num].r=r; tree[num].mid=(l+r)>>1; tree[num].cov=0;//cov表示该区间[l,r],是否被完全覆盖 if(l!=r) { int mid=tree[num].mid; build(l,mid,num<<1); build(mid+1,r,(num<<1)|1); } } void insert(int l,int r,int num,int val) { if(ls[tree[num].l]==l&&ls[tree[num].r]==r)//l,r和该区间两端的真值比较 { tree[num].cov=val; return; } if(tree[num].cov)//如果已经覆盖,先将子区间覆盖,然后标记该区间为未被完全覆盖 { tree[num<<1].cov=tree[(num<<1)|1].cov=tree[num].cov; tree[num].cov=0; } int mid=ls[tree[num].mid]; if(r<=mid) insert(l,r,num<<1,val); else if(l>mid) insert(l,r,(num<<1)|1,val); else { insert(l,mid,num<<1,val); insert(ls[tree[num].mid+1],r,(num<<1)|1,val);//注意,这里区间的左边传入的值,是ls[tree[num].mid+1]而不是mid+1... } } void query(int l,int r,int num) { if(tree[num].cov)//若该区间被完全覆盖,返回。 { flag[tree[num].cov]=1; return; } int mid=tree[num].mid; if(r<=mid) query(l,r,num<<1); else if(l>mid) query(l,r,(num<<1)|1); else { query(l,mid,num<<1); query(mid+1,r,(num<<1)|1); } } int main() { int t,n,i,j,len,cnt; scanf("%d",&t); while(t--) { memset(s,0,sizeof(s)); memset(ls,0,sizeof(ls)); scanf(" %d",&n); for(i=1,j=0;i<=n;++i) { scanf(" %d%d",&po[i].l,&po[i].r); s[++j]=po[i].l; s[++j]=po[i].r; } sort(s+1,s+j+1); for(i=1,len=0;i<=j;i++) { ls[++len]=s[i]; while(s[i+1]==s[i]) i++; }//离散结束,把不重复的点离散到区间[1,len]。ls[i],对应的是真值 build(1,len,1); for(i=1;i<=n;++i) insert(po[i].l,po[i].r,1,i); memset(flag,0,sizeof(flag)); query(1,len,1); for(i=1,cnt=0;i<=n;++i) { if(flag[i]) cnt++; } printf("%d/n",cnt); } return 0; } 

    最新回复(0)