首先肯定考虑树剖,这里没有要求区间加,所以可以用树状数组维护,不会卡常的
这里是边权,可以转化为点权:让每条边连接的较深的节点的点权等于边权即可,然后计算的时候减去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 }