• 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA


    【BZOJ4999】This Problem Is Too Simple!

    Description

    给您一颗树,每个节点有个初始值。
    现在支持以下两种操作:
    1. C i x(0<=x<2^31) 表示将i节点的值改为x。
    2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

    Input

    第一行有两个整数N,Q(1 ≤N≤ 100,000;1 ≤Q≤ 200,000),分别表示节点个数和操作个数。
    下面一行N个整数,表示初始时每个节点的初始值。
    接下来N-1行,每行两个整数x,y,表示x节点与y节点之间有边直接相连(描述一颗树)。
    接下来Q行,每行表示一个操作,操作的描述已经在题目描述中给出。

    Output

    对于每个Q输出单独一行表示所求的答案。

    Sample Input

    5 6
    10 20 30 40 50
    1 2
    1 3
    3 4
    3 5
    Q 2 3 40
    C 1 40
    Q 2 3 40
    Q 4 5 30
    C 3 10
    Q 4 5 30

    Sample Output

    0
    1
    1
    0

    题解:由于每种颜色相互独立,可以考虑离线。将修改操作变成一个颜色的删除操作和另一个颜色的加入操作,然后将所有操作和询问都按颜色和时间排序,分别处理每一个颜色。然后我们只需要倍增LCA+动态维护所有点到根路径上的权值即可。单点权值+a等于它子树中所有点到根路径上的权值都+a,所以用树状数组维护DFS序即可。

    竟然因为数组开小而WA了一天~

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=200010;
    int n,m,Q,cnt,now,tot;
    struct node
    {
    	int col,x,val,tim;
    }p[maxn*5];
    struct QUERY
    {
    	int col,a,b,tim,org;
    }q[maxn];
    char str[10];
    int to[maxn<<1],next[maxn<<1],head[maxn],p1[maxn],p2[maxn],dep[maxn],fa[19][maxn],v[maxn];
    int Log[maxn],s[maxn],vis[maxn],ans[maxn];
    void add(int a,int b)
    {
    	to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
    }
    void dfs(int x)
    {
    	p1[x]=++p2[0];
    	for(int i=head[x];i!=-1;i=next[i])	if(to[i]!=fa[0][x])
    		fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
    	p2[x]=p2[0];
    }
    bool cmpp(node a,node b)
    {
    	return (a.col==b.col)?(a.tim<b.tim):(a.col<b.col);
    }
    bool cmpq(QUERY a,QUERY b)
    {
    	return (a.col==b.col)?(a.tim<b.tim):(a.col<b.col);
    }
    void updata(int x,int val)
    {
    	for(int i=x;i<=n;i+=i&-i)
    	{
    		if(vis[i]<now)	vis[i]=now,s[i]=0;
    		s[i]+=val;
    	}
    }
    int query(int x)
    {
    	int i,ret=0;
    	for(i=x;i;i-=i&-i)
    	{
    		if(vis[i]<now)	vis[i]=now,s[i]=0;
    		ret+=s[i];
    	}
    	return ret;
    }
    int lca(int a,int b)
    {
    	if(dep[a]<dep[b])	swap(a,b);
    	for(int i=Log[dep[a]-dep[b]];i>=0;i--)	if(dep[fa[i][a]]>=dep[b])	a=fa[i][a];
    	if(a==b)	return a;
    	for(int i=Log[dep[a]];i>=0;i--)	if(fa[i][a]!=fa[i][b])	a=fa[i][a],b=fa[i][b];
    	return fa[0][a];
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,c;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<=n;i++)	v[i]=p[++tot].col=rd(),p[tot].x=i,p[tot].tim=0,p[tot].val=1;
    	for(i=2;i<=n;i++)	a=rd(),b=rd(),add(a,b),add(b,a);
    	dep[1]=1,dfs(1);
    	for(i=2;i<=n;i++)	Log[i]=Log[i>>1]+1;
    	for(j=1;(1<<j)<=n;j++)	for(i=1;i<=n;i++)	fa[j][i]=fa[j-1][fa[j-1][i]];
    	for(i=1;i<=m;i++)
    	{
    		scanf("%s",str),a=rd(),b=rd();
    		if(str[0]=='C')
    		{
    			tot+=2,p[tot-1].x=p[tot].x=a,p[tot-1].col=v[a],v[a]=p[tot].col=b;
    			p[tot-1].tim=p[tot].tim=i,p[tot-1].val=-1,p[tot].val=1;
    		}
    		else	q[++Q].a=a,q[Q].b=b,q[Q].col=rd(),q[Q].org=Q,q[Q].tim=i;
    	}
    	sort(p+1,p+tot+1,cmpp);
    	sort(q+1,q+Q+1,cmpq);
    	for(i=j=1;i<=Q;i++)
    	{
    		for(;(p[j].col<q[i].col||(p[j].col==q[i].col&&p[j].tim<q[i].tim))&&j<=tot;j++)
    		{
    			now=p[j].col;
    			updata(p1[p[j].x],p[j].val),updata(p2[p[j].x]+1,-p[j].val);
    		}
    		if(now==q[i].col)
    		{
    			a=q[i].a,b=q[i].b,c=lca(a,b);
    			ans[q[i].org]=query(p1[a])+query(p1[b])-query(p1[c])-query(p1[fa[0][c]]);
    		}
    	}
    	for(i=1;i<=Q;i++)	printf("%d
    ",ans[i]);
    	return 0;
    }

     

  • 相关阅读:
    博客园自动生成目录及页面美化
    Maven个人手册
    log4j日志工具
    redis教程(整理中)
    linux集群时钟问题
    Flex远程访问获取数据--HTTPService
    gm: error while loading shared libraries: libpng15.so.15: cannot open shared object file: No such file or directory
    SecureCRT中 secureCRT使用VIM时对语法高亮
    openresty安装
    FlashBuilder 4.6序列号破解
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7468744.html
Copyright © 2020-2023  润新知