zoukankan      html  css  js  c++  java
  • 【SDOI 2011】Paint 染色

      http://www.zybbs.org/JudgeOnline/problem.php?id=2243

      题目大意:给你一棵树,节点有颜色,要求可以查询某路径中连续颜色段的数目和修改某一段路径的颜色。

      两次拉实之后查询和修改即可。

      

    #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;
    }
    
  • 相关阅读:
    让 vscode 作为 SpringBoot,Java,Maven,甚至于 JavaScript,C,C++,Python,Php等多语言的开发工具吧!
    MySQL 连接错误集锦
    前端开发工具库:包含事件委托,动画处理,以及大部分常用的前端工具
    初探 Node.js 框架:eggjs (环境搭配篇)
    如何快速搭建一个 Node.JS 项目并进入开发?
    关于 JavaSrcipt 前端开发的建议:模块化开发
    Spring-Session 会话共享 -> 基于 Redis 集群,内附各大错误合集,包括配置,类寻找不到、连接错误等
    Java Email 邮件发送
    CSS 显示或隐藏子元素
    Ubuntu美化及配置,常见问题解决方案(仿 Mac 风格)
  • 原文地址:https://www.cnblogs.com/Delostik/p/2134544.html
Copyright © 2011-2022 走看看