zoukankan      html  css  js  c++  java
  • Water Tree

    Codeforces Round #200 (Div. 1) D:http://codeforces.com/problemset/problem/343/D

    题意:给你一颗有根树,树的每个节点有一个装水的东西,然后付亲的水可以流向儿子。一开始树上每个节点都是空的,然后会有两种操作。1 v,表示把v节点为子树的每个点都灌满水,2 v,表示v及v的祖先都清空。3 v是询问 v节点是否为空,为空输出0,否则输出1.

    题解:首先,树上操作可以通过DFS,然后转化成数组操作。3操作来说,只要v的子树中有一个0,那么v一定是0,所以把单点查询,转化成了区间查询。2操作来说,我们可以只进行单点更新,即只对v这个节点操作。1操作的时候,就是区间更新,但是这里首先要查询v中是否有0,因为2操作只到了点。加入说,之前 2 v,那么v及其父亲应该是0的,这时候如果1,v的话,那么必须要把v的父亲变为0.这里有两种实现。先说一种好写。set运用。我们一开始把树上的每个节点都放进set,表示每个几点都是0.对于操作1.来说,首先我们要查询是否有0,Q.lower_bound(ll[temp]),如果找到并且这个数的位置不超过rr[temp],那么v的父亲要变成0,即可v的父亲查到set中,同时把那些变成1的元素从set中删除,Q.erase(Q.lower_bound(ll[temp]),Q.upper_bound(rr[temp]));3操作类似。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<set>
     6 using namespace std;
     7 const int N=5e5+10;
     8 int head[N],now;
     9 int fa[N],ll[N],rr[N],cnt;
    10 set<int>Q;
    11 void init(){
    12      memset(head,-1,sizeof(head));
    13      memset(rr,0,sizeof(rr));
    14      memset(ll,0,sizeof(ll));
    15      memset(fa,0,sizeof(fa));
    16      now=0;
    17      cnt=0;
    18 }
    19 struct Node{
    20   int v;
    21   int next;
    22 }edge[N*2];
    23 void add(int u,int v){
    24    edge[cnt].v=v;
    25    edge[cnt].next=head[u];
    26    head[u]=cnt++;
    27 }
    28 void DFS(int u,int f){
    29      ll[u]=rr[u]=++now;
    30      Q.insert(now);
    31      fa[u]=f;
    32      for(int i=head[u];i!=-1;i=edge[i].next){
    33         int v=edge[i].v;
    34         if(v!=f)
    35             DFS(v,u);
    36      }
    37      rr[u]=now;
    38 }
    39 int n,m,t1,t2;
    40 int main(){
    41     while(~scanf("%d",&n)){
    42             init();
    43         for(int i=1;i<n;i++){
    44             scanf("%d%d",&t1,&t2);
    45             add(t1,t2);add(t2,t1);
    46         }
    47         DFS(1,0);
    48         scanf("%d",&m);
    49         for(int i=1;i<=m;i++){
    50             scanf("%d%d",&t1,&t2);
    51             if(t1==1){
    52                   bool flag=false;
    53                 set<int>::iterator it=Q.lower_bound(ll[t2]);
    54                 if(it==Q.end()||(*it)>rr[t2])
    55                    flag=true;
    56             Q.erase(Q.lower_bound(ll[t2]),Q.upper_bound(rr[t2]));
    57                 if(!flag&&t2!=1)
    58                     Q.insert(ll[fa[t2]]);
    59             }
    60             else if(t1==2){
    61                 Q.insert(ll[t2]);
    62             }
    63             else {
    64                 set<int>::iterator it=Q.lower_bound(ll[t2]);
    65                 if(it==Q.end()||(*it)>rr[t2])
    66                    printf("1
    ");
    67                    else
    68                     printf("0
    ");
    69             }
    70         }
    71     }
    72 }
    View Code

     第二种实现:线段树版本。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<set>
      6 using namespace std;
      7 const int N=5e5+10;
      8 int head[N],now;
      9 int fa[N],ll[N],rr[N],cnt;
     10 int n,m,t1,t2;
     11 int lazy[N*4],seg[N*4];
     12 void init(){
     13      memset(head,-1,sizeof(head));
     14      memset(rr,0,sizeof(rr));
     15      memset(ll,0,sizeof(ll));
     16      memset(fa,0,sizeof(fa));
     17      memset(lazy,0,sizeof(lazy));
     18      memset(seg,0,sizeof(seg));
     19      now=0;
     20      cnt=0;
     21 }
     22 struct Node{
     23   int v;
     24   int next;
     25 }edge[N*2];
     26 void add(int u,int v){
     27    edge[cnt].v=v;
     28    edge[cnt].next=head[u];
     29    head[u]=cnt++;
     30 }
     31 void DFS(int u,int f){
     32      ll[u]=rr[u]=++now;
     33      fa[u]=f;
     34      for(int i=head[u];i!=-1;i=edge[i].next){
     35         int v=edge[i].v;
     36         if(v!=f)
     37             DFS(v,u);
     38      }
     39      rr[u]=now;
     40 }
     41 void push_up(int rt){
     42   seg[rt]=min(seg[rt<<1],seg[rt<<1|1]);
     43 }
     44 void pushdown(int rt){
     45   if(lazy[rt]>0){
     46     lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
     47     seg[rt<<1]=seg[rt<<1|1]=seg[rt];
     48     lazy[rt]=-1;
     49   }
     50 }
     51 void update(int l,int r,int rt,int x,int y){
     52     if(l==x&&y==r){
     53         lazy[rt]=seg[rt]=1;
     54         return;
     55     }
     56     pushdown(rt);
     57    int mid=(l+r)/2;
     58    if(mid>=y)update(l,mid,rt<<1,x,y);
     59    else if(mid<x)update(mid+1,r,rt<<1|1,x,y);
     60    else {
     61       update(l,mid,rt<<1,x,mid);
     62       update(mid+1,r,rt<<1|1,mid+1,y);
     63    }
     64    push_up(rt);
     65 }
     66 void update1(int l,int r,int rt,int x){
     67     if(l==r){
     68         lazy[rt]=seg[rt]=0;
     69         return;
     70     }
     71    pushdown(rt);
     72    int mid=(l+r)/2;
     73    if(mid>=x)update1(l,mid,rt<<1,x);
     74    else update1(mid+1,r,rt<<1|1,x);
     75    push_up(rt);
     76 }
     77 int query(int l,int r,int rt,int x,int y){
     78     if(l==x&&r==y){
     79         return seg[rt];
     80     }
     81     pushdown(rt);
     82     int mid=(l+r)/2;
     83     if(mid>=y)return query(l,mid,rt<<1,x,y);
     84     else if(mid<x) return query(mid+1,r,rt<<1|1,x,y);
     85     else {
     86         return min(query(l,mid,rt<<1,x,mid),query(mid+1,r,rt<<1|1,mid+1,y));
     87     }
     88 }
     89 
     90 int main(){
     91     while(~scanf("%d",&n)){
     92             init();
     93         for(int i=1;i<n;i++){
     94             scanf("%d%d",&t1,&t2);
     95             add(t1,t2);add(t2,t1);
     96         }
     97         DFS(1,0);
     98         scanf("%d",&m);
     99         for(int i=1;i<=m;i++){
    100             scanf("%d%d",&t1,&t2);
    101             if(t1==1){
    102                 int temp=query(1,now,1,ll[t2],rr[t2]);
    103                 update(1,now,1,ll[t2],rr[t2]);
    104                 if(temp==0&&t2!=1)
    105                     update1(1,now,1,ll[fa[t2]]);
    106             }
    107             else if(t1==2){
    108                  update1(1,now,1,ll[t2]);
    109             }
    110             else {
    111                 printf("%d
    ",query(1,now,1,ll[t2],rr[t2]));
    112             }
    113         }
    114     }
    115 }
    View Code
  • 相关阅读:
    sql server执行存储过程慢的问题
    Windows service
    moss网站模板的一些问题
    ACM题解报告——HD1012
    ACM题解报告——HD1496
    ACM题解报告——HD1253
    ACM题解报告——进制数取于余
    ACM题解报告——HD1058
    ACM题解报告——HD1548
    ACM解题报告HD1015
  • 原文地址:https://www.cnblogs.com/chujian123/p/3898713.html
Copyright © 2011-2022 走看看