其实还是比较好做的,树链剖分现在越来越熟练了。对于这道题来说,所有的部落一开始全部在停战状态,所以它们的边权先初始赋为0,对于一个开战操作,就把链接这两个点的边上的边权赋一个大于0的数,查询时若是有和大于0的时候,我们便认为不能走。如果U停战操作,我们在C的时候要注意保存每一次开战的顺序,开展的村庄编号,停战的时候便将它们之间的边权赋为0。
代码如下:

1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e6+7;
4 const int INF=0x3f3f3f3f;
5 struct node{
6 int nxt,to,val;
7 }edge[maxn*3];
8 struct node1{
9 int l,r,sum,lazy;
10 }tree[maxn*4];
11 struct node2{
12 int u,v;
13 }st[maxn*2];
14 int head[maxn],cnt;
15 void add(int x,int y){
16 edge[++cnt].nxt=head[x];
17 edge[cnt].to=y;
18 edge[cnt].val=0;
19 head[x]=cnt;
20 }
21 int n,m,kkk,x,y;
22 int q1,q2;
23 int ljb;
24 char opt[666];
25 int dep[maxn],son[maxn],fa[maxn],size[maxn],dfn[maxn],top[maxn],va[maxn],w[maxn],Time;
26 void dfs1(int x,int f){
27 size[x]=1;
28 fa[x]=f;
29 dep[x]=dep[f]+1;
30 int maxson=-1;
31 for(int i=head[x];i;i=edge[i].nxt){
32 int go=edge[i].to;
33 if(go==fa[x]) continue;
34 w[go]=edge[i].val;
35 dfs1(go,x);
36 if(size[go]>maxson){
37 maxson=size[go];
38 son[x]=go;
39 }
40 }
41 }
42 void dfs2(int x,int topf){
43 top[x]=topf;
44 dfn[x]=++Time;
45 va[dfn[x]]=w[x];
46 if(!son[x]) return;
47 dfs2(son[x],topf);
48 for(int i=head[x];i;i=edge[i].nxt){
49 int go=edge[i].to;
50 if(go==fa[x]||go==son[x]) continue;
51 dfs2(go,go);
52 }
53 }
54 void build(int now,int l,int r){
55 tree[now].l=l,tree[now].r=r,tree[now].lazy=-1;
56 if(l==r){
57 tree[now].sum=va[l];
58 return;
59 }
60 int mid=(l+r)>>1;
61 build(now<<1,l,mid);
62 build(now<<1|1,mid+1,r);
63 tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
64 }
65 void pushdown(int now){
66 if(tree[now].lazy!=-1){
67 tree[now<<1].sum=(tree[now<<1].r-tree[now<<1].l+1)*tree[now].lazy;
68 tree[now<<1|1].sum=(tree[now<<1|1].r-tree[now<<1|1].l+1)*tree[now].lazy;
69 tree[now<<1].lazy=tree[now].lazy;
70 tree[now<<1|1].lazy=tree[now].lazy;
71 tree[now].lazy=-1;
72 }
73 }
74 void update(int now,int l,int r,int v){
75 if(tree[now].l>=l&&tree[now].r<=r){
76 tree[now].sum=(tree[now].r-tree[now].l+1)*v;
77 tree[now].lazy=v;
78 return;
79 }
80 pushdown(now);
81 int mid=(tree[now].l+tree[now].r)>>1;
82 if(l<=mid) update(now<<1,l,r,v);
83 if(r>mid) update(now<<1|1,l,r,v);
84 tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
85 }
86 int query(int now,int l,int r){
87 if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum;
88 pushdown(now);
89 int vak=0;
90 int mid=(tree[now].l+tree[now].r)>>1;
91 if(l<=mid) vak+=query(now<<1,l,r);
92 if(r>mid) vak+=query(now<<1|1,l,r);
93 return vak;
94 }
95 int link(int u,int v){
96 if(u==v) return 0;
97 int ans=0;
98 while(top[u]!=top[v]){
99 if(dep[top[u]]<dep[top[v]]) swap(u,v);
100 ans+=query(1,dfn[top[u]],dfn[u]);
101 u=fa[top[u]];
102 }
103 if(dep[u]<dep[v]) swap(u,v);
104 ans+=query(1,dfn[v]+1,dfn[u]);
105 return ans;
106 }
107 int main(){
108 scanf("%d%d",&n,&m);
109 for(int i=1;i<n;i++){
110 scanf("%d%d",&x,&y);
111 add(x,y);add(y,x);
112 }
113 dfs1(1,0);
114 dfs2(1,1);
115 build(1,1,n);
116 for(int i=1;i<=m;i++){
117 scanf("%s",opt);
118 if(opt[0]=='Q'){
119 scanf("%d%d",&q1,&q2);
120 int ans=link(q1,q2);
121 if(ans>0){
122 printf("No\n");
123 }
124 else printf("Yes\n");
125 }
126 if(opt[0]=='C'){
127 scanf("%d%d",&q1,&q2);
128 int who=dep[q1]<dep[q2]?q2:q1;
129 update(1,dfn[who],dfn[who],1);
130 st[++kkk].u=q1;
131 st[kkk].v=q2;
132 }
133 if(opt[0]=='U'){
134 scanf("%d",&ljb);
135 int who=dep[st[ljb].u]<dep[st[ljb].v]?st[ljb].v:st[ljb].u;
136 update(1,dfn[who],dfn[who],0);
137 }
138 }
139 return 0;
140 }
来源:https://www.cnblogs.com/LJB666/p/11375536.html
