【SDOI 2011】Paint 染色
生活随笔
收集整理的這篇文章主要介紹了
【SDOI 2011】Paint 染色
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://www.zybbs.org/JudgeOnline/problem.php?id=2243
題目大意:給你一棵樹,節(jié)點有顏色,要求可以查詢某路徑中連續(xù)顏色段的數(shù)目和修改某一段路徑的顏色。
兩次拉實之后查詢和修改即可。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #define NIL LCT #define MM 200001 #define MN 100001 using namespace std;queue<int> q; int n,m,a,b,c,color[MN]; char s[10]; struct EDGE{int pnt;EDGE *pre;EDGE (){}EDGE(int _pnt,EDGE *_pre):pnt(_pnt),pre(_pre){} }Edge[MM],*EP=Edge,*edge[MM];inline void addedge(int a,int b){edge[a]=new(++EP)EDGE(b,edge[a]);edge[b]=new(++EP)EDGE(a,edge[b]); }struct LinkCutTree{struct NODE{int c,lc,rc,mark,cnt;bool root;NODE *left,*right,*father;NODE (){}NODE(int _c,NODE *_left,NODE *_right,NODE *_father):c(_c),lc(_c),rc(_c),left(_left),right(_right),father(_father){mark=0,cnt=1,root=true;}}LCT[MN],*NP,*node[MN];void init(){NP=NIL;NIL->c=NIL->lc=NIL->rc=NIL->mark=0;NIL->left=NIL->right=NIL->father=NIL;NIL->root=false;}void build(){q.push(1);node[1]=new(++NP)NODE(color[1],NIL,NIL,NIL);while(!q.empty()){int i=q.front();q.pop();for(EDGE *j=edge[i];j;j=j->pre)if(node[j->pnt]!=node[i]->father){node[j->pnt]=new(++NP)NODE(color[j->pnt],NIL,NIL,node[i]);q.push(j->pnt);}}}void renew(NODE *&t,int key){if(t!=NIL) t->c=t->lc=t->rc=t->mark=key,t->cnt=1;}void pushdown(NODE *&t){if(t->mark){renew(t->left,t->mark);renew(t->right,t->mark);t->mark=0;}}void update(NODE *&t){t->lc=t->rc=t->c;if(t->left!=NIL) t->lc=t->left->lc;if(t->right!=NIL) t->rc=t->right->rc;t->cnt=t->left->cnt+t->right->cnt+1;if(t->c==t->left->rc) t->cnt--;if(t->c==t->right->lc) t->cnt--;}void zig(NODE *&t){NODE *f=t->father,*r=t->right;pushdown(f);pushdown(t);t->father=f->father;if(f->root) t->root=true,f->root=false;else{if(f->father->left==f) f->father->left=t;else f->father->right=t;}t->right=f,f->father=t,f->left=r,r->father=f;update(f);}void zag(NODE *&t){NODE *f=t->father,*l=t->left;pushdown(f);pushdown(t);t->father=f->father;if(f->root) t->root=true,f->root=false;else{if(f->father->left==f) f->father->left=t;else f->father->right=t;}t->left=f,f->father=t,f->right=l,l->father=f;update(f);}void splay(NODE *&t){pushdown(t);while(!t->root){if(t->father->root){if(t->father->left==t) zig(t);else zag(t);}else{if(t->father->father->left==t->father){if(t->father->left==t) zig(t->father),zig(t);else zag(t),zig(t);}else{if(t->father->left==t) zig(t),zag(t);else zag(t->father),zag(t);}}}update(t);}void Expose(NODE *&t){NODE *p=t,*q=NIL;while(p!=NIL){splay(p);p->right->root=true;p->right=q;p->right->root=false;update(p);q=p;p=p->father;}}void Modify(int a,int b,int c){Expose(node[a]);NODE *p=node[b],*q=NIL;while(p!=NIL){splay(p);if(p->father==NIL){p->c=c;renew(p->right,c);renew(q,c);}p->right->root=true;p->right=q;p->right->root=false;update(p);q=p;p=p->father;}}void query(int a,int b){Expose(node[a]);NODE *p=node[b],*q=NIL;while(p!=NIL){splay(p);if(p->father==NIL){int ans=q->cnt+p->right->cnt+1;if(p->c==q->lc) ans--;if(p->c==p->right->lc) ans--;printf("%d\n",ans);}p->right->root=true;p->right=q;p->right->root=false;update(p);q=p;p=p->father;}} }tree;int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&color[i]);for(int i=1;i<n;i++){scanf("%d%d",&a,&b);addedge(a,b);}tree.init();tree.build();while(m--){scanf("%s",s);if(s[0]=='Q'){scanf("%d%d",&a,&b);tree.query(a,b);}else{scanf("%d%d%d",&a,&b,&c);tree.Modify(a,b,c);}}return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/Delostik/archive/2011/08/11/2134544.html
總結(jié)
以上是生活随笔為你收集整理的【SDOI 2011】Paint 染色的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu系统---C++之Eclip
- 下一篇: C++中的结构体函数