zoukankan      html  css  js  c++  java
  • bzoj2243【SDOI2011】染色

    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 4537  Solved: 1702
    [Submit][Status][Discuss]

    Description

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

    1、将节点a到节点b路径上全部点都染成颜色c

    2、询问节点a到节点b路径上的颜色段数量(连续同样颜色被觉得是同一段)。如“1122213段组成:“11、“222和“1

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

    Input

    第一行包括2个整数nm,分别表示节点数和操作数;

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

    以下 行每行包括两个整数xy,表示xy之间有一条无向边。

    以下 行每行描写叙述一个操作:

    “C a b c”表示这是一个染色操作。把节点a到节点b路径上全部点(包含ab)都染成颜色c

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

    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




    有关链的操作,非常显然树链剖分+线段树维护区间。




    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #define F(i,j,n) for(int i=j;i<=n;i++)
    #define D(i,j,n) for(int i=j;i>=n;i--)
    #define ll long long
    #define maxn 100005
    using namespace std;
    struct seg{int l,r,lc,rc,s,tag;}t[maxn*4];
    struct edge_type{int next,to;}e[maxn*2];
    int n,m,x,y,z,cnt,tot;
    int head[maxn],d[maxn],son[maxn],belong[maxn],p[maxn],a[maxn],f[maxn][18];
    char ch;
    bool vst[maxn];
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    inline void add_edge(int x,int y)
    {
    	e[++cnt]=(edge_type){head[x],y};head[x]=cnt;
    	e[++cnt]=(edge_type){head[y],x};head[y]=cnt;
    }
    inline void dfs1(int x)
    {
    	vst[x]=true;son[x]=1;
    	for(int i=1;i<=17;i++)
    	{
    		if (d[x]<(1<<i)) break;
    		f[x][i]=f[f[x][i-1]][i-1];
    	}
    	for(int i=head[x];i;i=e[i].next)
    	{
    		if (vst[e[i].to]) continue;
    		d[e[i].to]=d[x]+1;
    		f[e[i].to][0]=x;
    		dfs1(e[i].to);
    		son[x]+=son[e[i].to];
    	}
    }
    inline void dfs2(int x,int chain)
    {
    	p[x]=++tot;belong[x]=chain;
    	int k=0;
    	for(int i=head[x];i;i=e[i].next)
    		if (d[e[i].to]>d[x]&&son[k]<son[e[i].to]) k=e[i].to;
    	if (!k) return;
    	dfs2(k,chain);
    	for(int i=head[x];i;i=e[i].next)
    		if (d[e[i].to]>d[x]&&e[i].to!=k) dfs2(e[i].to,e[i].to);
    }
    inline int lca(int x,int y)
    {
    	if (d[x]<d[y]) swap(x,y);
    	int t=d[x]-d[y];
    	F(i,0,17) if (t&(1<<i)) x=f[x][i];
    	if (x==y) return x;
    	D(i,17,0) if (f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}
    	return f[x][0];
    }
    inline void build(int k,int l,int r)
    {
    	t[k].l=l;t[k].r=r;t[k].s=1;t[k].tag=-1;
    	if (l==r) return;
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    }
    inline void pushup(int k)
    {
    	t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc;
    	if (t[k<<1].rc==t[k<<1|1].lc) t[k].s=t[k<<1].s+t[k<<1|1].s-1;
    	else t[k].s=t[k<<1].s+t[k<<1|1].s;
    }
    inline void update(int k,int z)
    {
    	t[k].tag=t[k].lc=t[k].rc=z;
    	t[k].s=1;
    }
    inline void pushdown(int k)
    {
    	if (t[k].tag==-1) return;
    	update(k<<1,t[k].tag);
    	update(k<<1|1,t[k].tag);
    	t[k].tag=-1;
    }
    inline void change(int k,int l,int r,int x)
    {
    	if (t[k].l==l&&t[k].r==r){update(k,x);return;}
    	pushdown(k);
    	int mid=(t[k].l+t[k].r)>>1;
    	if (r<=mid) change(k<<1,l,r,x);
    	else if (l>mid) change(k<<1|1,l,r,x);
    	else{change(k<<1,l,mid,x);change(k<<1|1,mid+1,r,x);}
    	pushup(k);
    }
    inline int ask(int k,int l,int r)
    {
    	if (t[k].l==l&&t[k].r==r) return t[k].s;
    	pushdown(k);
    	int mid=(t[k].l+t[k].r)>>1;
    	if (r<=mid) return ask(k<<1,l,r);
    	else if (l>mid) return ask(k<<1|1,l,r);
    	else
    	{
    		int tmp=t[k<<1].rc==t[k<<1|1].lc;
    		return ask(k<<1,l,mid)+ask(k<<1|1,mid+1,r)-tmp;
    	}
    }
    inline int getc(int k,int pos)
    {
    	if (t[k].l==t[k].r) return t[k].lc;
    	pushdown(k);
    	int mid=(t[k].l+t[k].r)>>1;
    	if (pos<=mid) return getc(k<<1,pos);
    	else return getc(k<<1|1,pos);
    }
    inline void solvechange(int x,int t,int c)
    {
    	while (belong[x]!=belong[t])
    	{
    		change(1,p[belong[x]],p[x],c);
    		x=f[belong[x]][0];
    	}
    	change(1,p[t],p[x],c);
    }
    inline int solvesum(int x,int t)
    {
    	int sum=0;
    	while (belong[x]!=belong[t])
    	{
    		sum+=ask(1,p[belong[x]],p[x]);
    		if (getc(1,p[belong[x]])==getc(1,p[f[belong[x]][0]])) sum--;
    		x=f[belong[x]][0];
    	}
    	sum+=ask(1,p[t],p[x]);
    	return sum;
    }
    int main()
    {
    	n=read();m=read();
    	F(i,1,n) a[i]=read();
    	F(i,1,n-1){x=read();y=read();add_edge(x,y);}
    	dfs1(1);
    	dfs2(1,1);
    	build(1,1,n);
    	F(i,1,n) change(1,p[i],p[i],a[i]);
    	F(i,1,m)
    	{
    		ch=getchar();
    		while (ch<'A'||ch>'Z') ch=getchar();
    		if (ch=='Q')
    		{
    			x=read();y=read();
    			int t=lca(x,y);
    			printf("%d
    ",solvesum(x,t)+solvesum(y,t)-1);
    		}
    		else
    		{
    			x=read();y=read();z=read();
    			int t=lca(x,y);
    			solvechange(x,t,z);solvechange(y,t,z);
    		}
    	}
    }
    


  • 相关阅读:
    LeetCode 109 Convert Sorted List to Binary Search Tree
    LeetCode 108 Convert Sorted Array to Binary Search Tree
    LeetCode 107. Binary Tree Level Order Traversal II
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 103 Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 104. Maximum Depth of Binary Tree
    接口和多态性
    C# 编码规范
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7019851.html
Copyright © 2011-2022 走看看