• bzoj2243:[SDOI2011]染色


    链剖就可以了。一开始的想法错了。但也非常接近了。妈呀调的要死。。。然后把字体再缩小一号查错起来比较容易QAQ。 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define lson l,mid,x<<1
    #define rson mid+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    } 
    const int nmax=1e5+5;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to;edge *next;
    };
    edge es[nmax<<1],*pt=es,*head[nmax];
    void add(int u,int v){
    	pt->to=v;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->next=head[v];head[v]=pt++;
    }
    int n,m,fa[nmax],son[nmax],dep[nmax],size[nmax],tp[nmax],id[nmax],idx[nmax],w[nmax];
    void dfs(int x){
    	size[x]=1;
    	qwq(x) if(o->to!=fa[x]){
    		int to=o->to;dep[to]=dep[x]+1,fa[to]=x;
    		dfs(o->to);size[x]+=size[to];
    		if(!son[x]||size[son[x]]<size[to]) son[x]=to;
    	}
    }
    void DFS(int x,int top){
    	tp[x]=top;id[++id[0]]=x;idx[x]=id[0];
    	if(son[x]) DFS(son[x],top);
    	qwq(x) if(!idx[o->to]) DFS(o->to,o->to);
    }
    
    int lc[nmax<<2],rc[nmax<<2],sum[nmax<<2],col[nmax<<2];
    void pushup(int x){
    	lc[x]=lc[x<<1];rc[x]=rc[x<<1|1];
    	sum[x]=sum[x<<1]+sum[x<<1|1]-(rc[x<<1]==lc[x<<1|1]);
    }
    void build(int l,int r,int x){
    	col[x]=-1;
    	if(l==r){
    		lc[x]=rc[x]=w[id[l]];sum[x]=1;return ;
    	}
    	int mid=(l+r)>>1;build(lson);build(rson);pushup(x);
    }
    void print(int l,int r,int x){
    	printf("%d->%d:%d %d %d %d
    ",l,r,col[x],lc[x],rc[x],sum[x]);
    	if(l==r) return ;
    	int mid=(l+r)>>1;print(lson);print(rson);
    }
    void pushdown(int x){
    	if(col[x]!=-1){
    		col[x<<1]=col[x<<1|1]=col[x];
    		lc[x<<1]=rc[x<<1]=lc[x<<1|1]=rc[x<<1|1]=col[x];
    		sum[x<<1]=sum[x<<1|1]=1;col[x]=-1;
    		return ;
    	}
    }
    void update(int tl,int tr,int p,int l,int r,int x){
    	if(tl<=l&&tr>=r){
    		col[x]=p;lc[x]=rc[x]=p;sum[x]=1;return ;
    	}
    	int mid=(l+r)>>1;pushdown(x);
    	if(tl<=mid) update(tl,tr,p,lson);
    	if(tr>mid) update(tl,tr,p,rson);
    	pushup(x);
    }
    void UPDATE(int a,int b,int p){
    	while(tp[a]!=tp[b]){
    		if(dep[tp[a]]>dep[tp[b]]) swap(a,b);
    		update(idx[tp[b]],idx[b],p,1,n,1);
    		b=fa[tp[b]];
    	}
    	if(dep[a]>dep[b]) swap(a,b);
    	update(idx[a],idx[b],p,1,n,1);
    }
    int query(int tl,int tr,int l,int r,int x){
    	if(tl<=l&&tr>=r) return sum[x];
    	int mid=(l+r)>>1;pushdown(x);
    	if(tr<=mid) return query(tl,tr,lson);
    	if(tl>mid) return query(tl,tr,rson);
    	return query(tl,tr,lson)+query(tl,tr,rson)-(rc[x<<1]==lc[x<<1|1]);
    }
    int get(int p,int l,int r,int x){
    	//printf("%d %d %d
    ",l,r,lc[x]);
    	if(l==r) return lc[x];
    	int mid=(l+r)>>1;pushdown(x);
    	return p<=mid?get(p,lson):get(p,rson);
    }
    void QUERY(int a,int b){
    	int ans=0; 
    	while(tp[a]!=tp[b]){
    		if(dep[tp[a]]>dep[tp[b]]) swap(a,b);
    		ans+=query(idx[tp[b]],idx[b],1,n,1);
    		//printf("%d %d %d %d %d
    ",ans,idx[fa[tp[b]]],get(idx[fa[tp[b]]],1,n,1),idx[tp[b]],get(idx[tp[b]],1,n,1));
    		if(get(idx[fa[tp[b]]],1,n,1)==get(idx[tp[b]],1,n,1)) ans--;
    		b=fa[tp[b]];
    	}
    	if(dep[a]>dep[b]) swap(a,b);
    	ans+=query(idx[a],idx[b],1,n,1);
    	printf("%d
    ",ans);
    }
    int main(){
    	n=read(),m=read();
    	rep(i,1,n) w[i]=read();
    	int u,v,d;
    	rep(i,1,n-1) u=read(),v=read(),add(u,v);
    	clr(son,0);clr(idx,0);dep[1]=0;id[0]=0;
    	dfs(1);DFS(1,1);
    	//rep(i,1,n) printf("%d %d %d %d %d %d
    ",fa[i],son[i],dep[i],size[i],tp[i],id[i]);
    	//rep(i,1,n) printf("%d ",id[i]);printf("
    ");
    	
    	build(1,n,1);
    	//print(1,n,1);
    	//get(2,1,n,1);
    	char s[5];
    	rep(i,1,m){
    		scanf("%s",s);u=read(),v=read();
    		if(s[0]=='C') d=read(),UPDATE(u,v,d);
    		else QUERY(u,v);
    	}
    	return 0;
    }
    

      

    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 5972  Solved: 2185
    [Submit][Status][Discuss]

    Description

     

    给定一棵有n个节点的无根树和m个操作,操作有2类:

    1、将节点a到节点b路径上所有点都染成颜色c;

    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”3段组成:“11”、“222”和“1”

    请你写一个程序依次完成这m个操作。

    Input

    第一行包含2个整数n和m,分别表示节点数和操作数;

    第二行包含n个正整数表示n个节点的初始颜色

    下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

    下面 行每行描述一个操作:

    “C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

    “Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

     

    Output

    对于每个询问操作,输出一行答案。

     

    Sample Input

    6 5

    2 2 1 2 1 1

    1 2

    1 3

    2 4

    2 5

    2 6

    Q 3 5

    C 2 1 1

    Q 3 5

    C 5 1 2

    Q 3 5

    Sample Output

    3

    1

    2

    HINT

    数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    【OpenXml】Pptx的边框虚线转为WPF的边框虚线
    C#系列文章索引
    了解LINQ
    【爬虫系列】2. 打开App逆向“潘多拉魔盒”
    Makefile基础
    设计原则 开闭原则
    设计模式 工厂方法模式
    设计原则 接口隔离原则
    设计原则 迪米特法则
    设计原则 单一职责原则
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5804183.html
Copyright © 2020-2023  润新知