首先肯定考虑树剖,这里没有要求区间加,所以可以用树状数组维护,不会卡常的

这里是边权,可以转化为点权:让每条边连接的较深的节点的点权等于边权即可,然后计算的时候减去lca

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define MAXN 300005
  6 #define LOG 20
  7 using namespace std;
  8 int read(){
  9     int x=0;char ch=getchar();
 10     while(ch<'0'||ch>'9'){ch=getchar();}
 11     while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
 12     return x;
 13 }
 14 int n,T;
 15 int a[MAXN],dat[MAXN];
 16 int dep[MAXN],size[MAXN],gs[MAXN],fa[20][MAXN];
 17 int top[MAXN],tree[MAXN],pre[MAXN],tot;
 18 int first[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt;
 19 int id[MAXN],tmp;
 20 
 21 void add(int x,int y){
 22     nxt[++cnt]=first[x];first[x]=cnt;to[cnt]=y;
 23     nxt[++cnt]=first[y];first[y]=cnt;to[cnt]=x;
 24 }
 25 int lca(int x,int y){
 26     if(dep[x]<dep[y]){
 27         swap(x,y);
 28     }
 29     for(int k=dep[x]-dep[y],p=0;k;k>>=1,p++){
 30         if(k&1){
 31             x=fa[p][x];
 32         }
 33     }
 34     if(x==y){
 35         return x;
 36     }
 37     for(int k=LOG-1;k>=0;k--){
 38         if(fa[k][x]!=fa[k][y]){
 39             x=fa[k][x],y=fa[k][y];
 40         }
 41     }
 42     return fa[0][x];
 43 }
 44 void change(int k,int x){
 45     while(k<=n){
 46         dat[k]+=x;
 47         k+=(k&-k);
 48     }
 49 }
 50 int query(int k){
 51     int ret=0;
 52     while(k>=1){
 53         ret+=dat[k];
 54         k-=(k&-k);
 55     }
 56     return ret;
 57 }
 58 void dfs1(int x){
 59     size[x]=1;
 60     for(int e=first[x];e;e=nxt[e]){
 61         int y=to[e];
 62         if(y==fa[0][x]){
 63             continue;
 64         }
 65         fa[0][y]=x;
 66         dep[y]=dep[x]+1;
 67         dfs1(y);
 68         size[x]+=size[y];
 69         if(size[y]>size[gs[x]]){
 70             gs[x]=y;
 71         }
 72     }
 73 }
 74 void dfs2(int x,int t){
 75     top[x]=t;
 76     tree[x]=(++tot);
 77     pre[tot]=x;
 78     if(!gs[x]){
 79         return;
 80     }
 81     dfs2(gs[x],t);
 82     for(int e=first[x];e;e=nxt[e]){
 83         int y=to[e];
 84         if(y==fa[0][x]||y==gs[x]){
 85             continue;
 86         }
 87         dfs2(y,y);
 88     }
 89 }
 90 int ask(int x,int y){
 91     int f1=top[x],f2=top[y];
 92     if(dep[f1]<dep[f2]){
 93         swap(x,y),swap(f1,f2);
 94     }
 95     int ret=-a[lca(x,y)];
 96     while(f1!=f2){
 97         ret+=query(tree[x])-query(tree[f1]-1);
 98         x=fa[0][f1]; f1=top[x];
 99         if(dep[f1]<dep[f2]){
100             swap(x,y),swap(f1,f2);
101         }    
102     }
103     if(dep[x]<dep[y]){
104         swap(x,y);
105     }
106     ret+=query(tree[x])-query(tree[y]-1);
107     return (ret<=0);
108 }
109 void init(){
110     n=read();T=read();
111     for(int i=1;i<n;i++){
112         int x=read(),y=read();
113         add(x,y);
114     }
115     dfs1(1);
116     dfs2(1,1);
117     for(int k=1;k<LOG;k++){
118         for(int i=1;i<=n;i++){
119             fa[k][i]=fa[k-1][fa[k-1][i]];
120         }
121     }
122 }
123 void solve(){
124     char ch[5];
125     while(T--){
126         scanf("%s",ch);
127         int x=read();
128         if('Q'==ch[0]){
129             int y=read();
130             if(ask(x,y)){
131                 printf("Yes\n");
132             }
133             else{
134                 printf("No\n");
135             }
136         }
137         else if('C'==ch[0]){
138             int y=read();
139             if(dep[x]<dep[y]){
140                 swap(x,y);
141             }
142             change(tree[x],1);
143             a[x]++;
144             id[++tmp]=x;
145         }
146         else{
147             x=id[x];
148             change(tree[x],-1);
149             a[x]--;
150         }
151     }
152 }
153 int main()
154 {
155     init();
156     solve();
157     return 0;
158 }
树剖AC

相关文章:

  • 2022-01-18
  • 2021-10-24
  • 2021-04-06
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-12
猜你喜欢
  • 2021-10-08
  • 2022-02-04
  • 2021-08-06
  • 2021-12-06
相关资源
相似解决方案