P3950 部落冲突 树链剖分

痴心易碎 提交于 2020-02-04 11:08:09

题目链接

其实还是比较好做的,树链剖分现在越来越熟练了。对于这道题来说,所有的部落一开始全部在停战状态,所以它们的边权先初始赋为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 } 
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!