zoukankan      html  css  js  c++  java
  • Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1、把某结点以及其各个祖先值设为0、询问某结点的值。

    对于第一个操作就是经典的DFS序+线段树了。而对于第二个操作,考虑再维护一个域表示各个结点为根的子树是否有进行第二个操作,如果有那么该结点应该就要是0;而在进行第一个操作前,看一下子树是否有进行第二个操作,如果有就整个标记成没有并把标记上传,让该结点的父亲结点标记成进行了第二个操作。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define MAXN 555555
      6 
      7 struct Edge{
      8     int v,next;
      9 }edge[MAXN<<1];
     10 int NE,head[MAXN];
     11 void addEdge(int u,int v){
     12     edge[NE].v=v; edge[NE].next=head[u];
     13     head[u]=NE++;
     14 }
     15 
     16 int l[MAXN],r[MAXN],par[MAXN],dfn;
     17 void dfs(int u,int fa){
     18     l[u]=++dfn;
     19     for(int i=head[u]; i!=-1; i=edge[i].next){
     20         int v=edge[i].v;
     21         if(v==fa) continue;
     22         par[v]=u;
     23         dfs(v,u);
     24     }
     25     r[u]=dfn;
     26 }
     27 
     28 int x,y,z,N;
     29 bool tree[MAXN<<2],down[MAXN<<2],up[MAXN<<2];
     30 void updateUp(int i,int j,int k){
     31     if(x<=i && j<=y){
     32         up[k]=z;
     33         return;
     34     }
     35     if(up[k]==0){
     36         up[k<<1]=0;
     37         up[k<<1|1]=0;
     38     }
     39     int mid=i+j>>1;
     40     if(x<=mid) updateUp(i,mid,k<<1);
     41     if(y>mid) updateUp(mid+1,j,k<<1|1);
     42     up[k]=up[k<<1]|up[k<<1|1];
     43 }
     44 bool queryUp(int i,int j,int k){
     45     if(x<=i && j<=y){
     46         return up[k];
     47     }
     48     if(up[k]==0){
     49         up[k<<1]=0;
     50         up[k<<1|1]=0;
     51     }
     52     int mid=i+j>>1; bool res=0;
     53     if(x<=mid) res|=queryUp(i,mid,k<<1);
     54     if(y>mid) res|=queryUp(mid+1,j,k<<1|1);
     55     return res;
     56 }
     57 
     58 void update(int i,int j,int k){
     59     if(x<=i && j<=y){
     60         tree[k]=z;
     61         down[k]=z;
     62         return;
     63     }
     64     if(down[k]==1){
     65         tree[k<<1]=1;
     66         tree[k<<1|1]=1;
     67         down[k<<1]=1;
     68         down[k<<1|1]=1;
     69         down[k]=0;
     70     }
     71     int mid=i+j>>1;
     72     if(x<=mid) update(i,mid,k<<1);
     73     if(y>mid) update(mid+1,j,k<<1|1);
     74 }
     75 bool query(int i,int j,int k){
     76     if(i==j){
     77         return tree[k];
     78     }
     79     if(down[k]==1){
     80         tree[k<<1]=1;
     81         tree[k<<1|1]=1;
     82         down[k<<1]=1;
     83         down[k<<1|1]=1;
     84         down[k]=0;
     85     }
     86     int mid=i+j>>1;
     87     if(x<=mid) return query(i,mid,k<<1);
     88     else query(mid+1,j,k<<1|1);
     89 }
     90 
     91 int main(){
     92     int n,q,a,b;
     93     scanf("%d",&n);
     94     memset(head,-1,sizeof(head));
     95     for(int i=1; i<n; ++i){
     96         scanf("%d%d",&a,&b);
     97         addEdge(a,b);
     98         addEdge(b,a);
     99     }
    100 
    101     for(N=1; N<n; N<<=1);
    102     dfs(1,1);
    103 
    104     scanf("%d",&q);
    105     while(q--){
    106         scanf("%d%d",&a,&b);
    107         if(a==1){
    108             x=l[b]; y=r[b];
    109             if(queryUp(1,N,1)){
    110                 z=0;
    111                 updateUp(1,N,1);
    112                 if(b!=1){
    113                     x=l[par[b]]; y=l[par[b]]; z=1;
    114                     updateUp(1,N,1);
    115                 }
    116             }
    117             x=l[b]; y=r[b]; z=1;
    118             update(1,N,1);
    119         }else if(a==2){
    120             x=l[b]; y=l[b]; z=1;
    121             updateUp(1,N,1);
    122         }else if(a==3){
    123             x=l[b]; y=r[b];
    124             if(queryUp(1,N,1)){
    125                 puts("0");
    126             }else{
    127                 x=l[b]; y=l[b];
    128                 printf("%d
    ",query(1,N,1));
    129             }
    130         }
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    安装gmsll
    常用LInux命令和操作
    yum 一键安装 jdk
    Linux目录详解,软件应该安装到哪个目录
    安装npm
    linux安装mysql (rpm + yum)
    springboot 打包jar 运行找资源文件
    rpm包安装java jar开机自启
    centos7设置服务开机自启
    linux(centos7) nginx 配置
  • 原文地址:https://www.cnblogs.com/WABoss/p/5681307.html
Copyright © 2011-2022 走看看