真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[BZOJ 4999]This Problem Is Too Simple!

[BZOJ 4999]This Problem Is Too Simple!

题目

给您一颗树,每个节点有个初始值。
现在支持以下两种操作:
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

OUTPUT

0

1

1

0

解题报告

树剖+权值线段树动态开点+离散

随便搞搞就行了

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<map>
  5 using namespace std;
  6 inline int read(){
  7     int sum(0);
  8     char ch(getchar());
  9     for(;ch<'0'||ch>'9';ch=getchar());
 10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 11     return sum;
 12 }
 13 struct edge{
 14     int e;
 15     edge *n;
 16 }ed[200005],*pre[100005];
 17 int tot;
 18 inline void insert(int s,int e){
 19     ed[++tot].e=e;
 20     ed[tot].n=pre[s];
 21     pre[s]=&ed[tot];
 22 }
 23 map<int,int>ma;
 24 int num;
 25 int n,q;
 26 int a[100005];
 27 int dep[100005],size[100005],fa[100005],son[100005];
 28 inline void dfs1(int u){
 29     size[u]=1;
 30     son[u]=0;
 31     for(edge *i=pre[u];i;i=i->n){
 32         int e(i->e);
 33         if(e!=fa[u]){
 34             fa[e]=u;
 35             dep[e]=dep[u]+1;
 36             dfs1(e);
 37             size[u]+=size[e];
 38             if(size[e]>size[son[u]])
 39                 son[u]=e;
 40         }
 41     }
 42 }
 43 int timee;
 44 int id[100005],pos[100005],top[100005];
 45 inline void dfs2(int u,int rt){
 46     top[u]=rt;
 47     id[u]=++timee;
 48     pos[timee]=u;
 49     if(son[u])
 50         dfs2(son[u],rt);
 51     for(edge *i=pre[u];i;i=i->n){
 52         int e(i->e);
 53         if(e!=fa[u]&&e!=son[u])
 54             dfs2(e,e);
 55     }
 56 }
 57 int cnt;
 58 int rt[300005],lch[12000005],rch[12000005],sum[12000005];
 59 inline void update(int &x,int pos,int w,int l,int r){
 60     if(!x)
 61         x=++cnt;
 62     sum[x]+=w;
 63     if(l==r)
 64         return;
 65     int mid((l+r)>>1);
 66     if(pos<=mid)
 67         update(lch[x],pos,w,l,mid);
 68     else
 69         update(rch[x],pos,w,mid+1,r);
 70 }
 71 inline int query(int x,int ll,int rr,int l,int r){
 72     if(!x)
 73         return 0;
 74     if(ll<=l&&r<=rr)
 75         return sum[x];
 76     int mid((l+r)>>1),ret(0);
 77     if(ll<=mid)
 78         ret+=query(lch[x],ll,rr,l,mid);
 79     if(mid<rr)
 80         ret+=query(rch[x],ll,rr,mid+1,r);
 81     return ret;
 82 }
 83 inline int ask(int x,int y,int z){
 84     int ret(0),tmp(ma[z]);
 85     while(top[x]^top[y]){
 86         if(dep[top[x]]<dep[top[y]])
 87             swap(x,y);
 88         ret+=query(rt[tmp],id[top[x]],id[x],1,n);
 89         x=fa[top[x]];
 90     }
 91     if(dep[x]>dep[y])
 92         swap(x,y);
 93     ret+=query(rt[tmp],id[x],id[y],1,n);
 94     return ret;
 95 }
 96 char op[2];
 97 int main(){
 98     memset(pre,NULL,sizeof(pre));
 99     n=read(),q=read();
100     for(int i=1;i<=n;++i)
101         a[i]=read();
102     for(int i=1;i<n;++i){
103         int x(read()),y(read());
104         insert(x,y),insert(y,x);
105     }
106     dfs1(1);
107     dfs2(1,1);
108     for(int i=1;i<=n;++i){
109         if(!ma[a[i]])
110             ma[a[i]]=++num;
111         update(rt[ma[a[i]]],id[i],1,1,n);
112     }
113     while(q--){
114         scanf("%s",op);
115         if(op[0]=='C'){
116             int x(read()),y(read());
117             update(rt[ma[a[x]]],id[x],-1,1,n);
118             if(!ma[y])
119                 ma[y]=++num;
120             a[x]=y;
121             update(rt[ma[y]],id[x],1,1,n);
122         }
123         else{
124             int x(read()),y(read()),z(read());
125             if(!ma[z])
126                 puts("0");
127             else
128                 printf("%d\n",ask(x,y,z));
129         }
130     }
131 }
View Code

 

posted @ 2017-09-26 21:13  Hzoi_Mafia  阅读(...)  评论(...编辑  收藏
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神