zoukankan      html  css  js  c++  java
  • P3950 部落冲突 树链剖分

    题目链接

    其实还是比较好做的,树链剖分现在越来越熟练了。对于这道题来说,所有的部落一开始全部在停战状态,所以它们的边权先初始赋为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
    ");
    123             }
    124             else printf("Yes
    ");
    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
  • 相关阅读:
    I/O多路复用技术
    网络编程的异常及处理
    LINUX的signal
    网络编程小知识
    一个位压缩技巧
    加密技术[翻译]
    暴雪的hash算法[翻译]
    喜欢就好
    【PYTHON】编码是个细致活
    【Python3】POP3协议收邮件
  • 原文地址:https://www.cnblogs.com/LJB666/p/11375536.html
Copyright © 2011-2022 走看看