Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
蒟蒻的ckw染色树的做法ckw染色树就是ckw染色线段数的简称…… 百度什么的可定搜不到…… 其核心内容就是ltag,rtag和ctag 能处理的问题……这道题就是模板 还有会场预约(这个应该更模板)等,尽管有更好的算法 但是用ckw染色树基本上可以做到无脑套用,然后复杂度依然是nlgn(虽然通常来讲会常数大一点),可以水过很多题目…… 当父节点的操作会影响到子节点的时候,我们显然需要记录子节点是否需要被修改(ltag,rtag)。通常这个修改就是撤销(delete_segment),最后需要的问题形如"有多少条线段还存活着",所以还需要O(q)的空间把询问操作记录下来。 ckw染色树可以做到在线询问。 对于这个题目的更新操作为例。 如果这个区间覆盖: 如果已经被染色,撤销当前的颜色。 对于这道题,记录一下当前颜色还剩下多少last。 query[ctag].last-=(right-left+1); 如果为0,就segment_cnt--,表示这条线段已经被全部删除掉了。 对于会场预约,直接把整条线段删除就好了(递归调用delete(整棵树的根节点,query[ctag].left,query[ctag].right),然后segment_cnt++)。 显然对于这道题目的delete操作是不需要再写一个函数的(因为不用递归),所以只有这个部分需要针对不同题目修改。 然后如果左子树有颜色(ltag==true),那么将左子树涂上颜色0(paint(rt->tc,0))并ltag=false。右子树同理。然后ctag=color;return; 如果这个区间没有被覆盖, 若和左子树区间有交集,递归涂色(paint(rt->rc,color))并ltag=1; 右子树同理。 然后说说会场预约的delete操作 没什么好说的,唯一一点,一个区间可能只是删除一部分,所以要返回一个值,表示这个区间及其子树是否没有颜色。 附上代码。一般ckw染色树的代码都很长…… //POJ2528 #include<cstdio> #include<algorithm> #include<vector> #define MAXM 10000 using namespace std; struct query{ int u,v,last; }q[MAXM+10]; struct segment{ int ctag,ltag,rtag; }seg[16*MAXM+10]; int segment_cnt=0; vector<int> vec; int init_segment(int rt,int lef,int rig) { seg[rt].ctag=seg[rt].ltag=seg[rt].rtag=0; if(lef==rig) return 0; int mid=(lef+rig)/2; init_segment(rt*2,lef,mid); init_segment(rt*2+1,mid+1,rig); return 0; } int push_down(int rt,int lef,int rig) { int mid=(lef+rig)/2; seg[rt*2].ctag=seg[rt].ctag; seg[rt*2+1].ctag=seg[rt].ctag; seg[rt].ctag=0;seg[rt].ltag=seg[rt].rtag=1; return 0; } int insert_segment(int root,int lef,int rig,int s,int t,int color) { int <=seg[root].ltag; int &rt=seg[root].rtag; int &ct=seg[root].ctag; int mid=(lef+rig)/2; if(s<=lef&&rig<=t) { if(ct!=0) { q[ct].last-=rig-lef+1; if(q[ct].last==0) segment_cnt--; } if(lt!=0) insert_segment(root*2,lef,mid,s,t,0); if(rt!=0) insert_segment(root*2+1,mid+1,rig,s,t,0); lt=rt=0;ct=color; return 0; } if(ct) push_down(root,lef,rig); if(s<=mid) insert_segment(root*2,lef,mid,s,t,color),lt=1; if(mid<t) insert_segment(root*2+1,mid+1,rig,s,t,color),rt=1; } int getid(int x) { return lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1; } int main() { int T,m,u,v;scanf("%d",&T); while(T--) { scanf("%d",&m); segment_cnt=m; for(int i=1;i<=m;i++) { scanf("%d%d",&q[i].u,&q[i].v); vec.push_back(q[i].u); vec.push_back(q[i].v); } sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end()); int n=vec.size()+2; init_segment(1,1,n); for(int i=1;i<=m;i++) { int idu=getid(q[i].u),idv=getid(q[i].v); q[i].last=idv-idu+1; insert_segment(1,1,n,idu,idv,i); } printf("%d\n",segment_cnt); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator