• [bzoj3553] [Shoi2014]三叉神经树


      链剖一波,我们只关心末端"001"和"011"这两种输入被改变后会改变输出的情况。。不然就是单点修改。

      线段树需要维护区间右端开始连续的"001""011"长度。。修改的时候就把整段连续的都改了,最后加个单点修改。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 using namespace std;
      5 const int maxn=500233;
      6 struct zs{
      7     int too,pre;
      8 }e[maxn];int tot1,last[maxn];
      9 int lc[maxn<<1],rc[maxn<<1],sz1[maxn<<1],mx0[maxn<<1],mx1[maxn<<1],tag[maxn<<1],tot;//0:001  1:110 2:000 3:111
     10 int bel[maxn],len[maxn],sz[maxn],dfn[maxn],tim,pos[maxn],st[maxn],top,rt[maxn];
     11 int mp[maxn*3],fa[maxn*3];
     12 int i,j,k,n,m,LEN,P,R;
     13 bool ans;
     14  
     15 int ra;char rx;
     16 inline int read(){
     17     rx=getchar(),ra=0;
     18     while(rx<'0'||rx>'9')rx=getchar();
     19     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     20 }
     21  
     22 inline void upd(int x){
     23     int l=lc[x],r=rc[x];
     24     mx0[x]=mx0[r]==sz1[r]?mx0[l]+mx0[r]:mx0[r],
     25     mx1[x]=mx1[r]==sz1[r]?mx1[l]+mx1[r]:mx1[r];
     26 }
     27 inline void pushdown(int x){
     28     int l=lc[x],r=rc[x];
     29     if(tag[x]==1)
     30         mx1[l]=sz1[l],mx1[r]=sz1[r],
     31         tag[r]=tag[l]=1,
     32         mx0[l]=mx0[r]=0,
     33         tag[x]=-1;
     34     if(tag[x]==0)
     35         mx0[l]=sz1[l],mx0[r]=sz1[r],
     36         tag[l]=tag[r]=0,
     37         mx1[l]=mx1[r]=0,
     38         tag[x]=-1;
     39 }
     40  
     41 void query0(int x,int a,int b){
     42 //  if(!mx0[x])return;
     43     if(b<=R&&mx0[x]==sz1[x]){
     44         LEN+=mx0[x],
     45         tag[x]=1,mx1[x]=sz1[x],mx0[x]=0;
     46         return;
     47     }
     48     if(R-LEN>b-mx1[x]||a==b)return;
     49     if(tag[x]!=-1)pushdown(x);
     50     int mid=a+b>>1;
     51     if(R>mid){
     52         query0(rc[x],mid+1,b);
     53         if(mid+LEN==R&&mx0[lc[x]])query0(lc[x],a,mid);
     54     }else query0(lc[x],a,mid);
     55     upd(x);
     56 }
     57 void query1(int x,int a,int b){
     58 //  if(!mx1[x])return;
     59     if(b<=R&&mx1[x]==sz1[x]){
     60         LEN+=mx1[x],
     61         tag[x]=0,mx0[x]=mx1[x],mx1[x]=0;
     62         return;
     63     }
     64     if(R-LEN>b-mx0[x]||a==b)return;
     65     if(tag[x]!=-1)pushdown(x);
     66     int mid=a+b>>1;
     67     if(R>mid){
     68         query1(rc[x],mid+1,b);
     69         if(mid+LEN==R)query1(lc[x],a,mid);
     70     }else query1(lc[x],a,mid);
     71     upd(x);
     72 }
     73 void add1(int x,int a,int b){
     74     if(a==b){
     75         if(tag[x]==1)tag[x]=3,mx1[x]=0;else
     76         if(tag[x]==2)tag[x]=0,mx0[x]=1;else puts("gg");
     77         return;
     78     }
     79     if(tag[x]!=-1)pushdown(x);
     80     int mid=a+b>>1;
     81     if(LEN<=mid)add1(lc[x],a,mid);else add1(rc[x],mid+1,b);
     82     upd(x);
     83 }
     84 void add0(int x,int a,int b){
     85     if(a==b){
     86         if(tag[x]==0)tag[x]=2,mx0[x]=0;else
     87         if(tag[x]==3)tag[x]=1,mx1[x]=1;else puts("gg");
     88         return;
     89     }
     90     if(tag[x]!=-1)pushdown(x);
     91     int mid=a+b>>1;
     92     if(LEN<=mid)add0(lc[x],a,mid);else add0(rc[x],mid+1,b);
     93     upd(x);
     94 }
     95  
     96 void build(int &x,int a,int b){
     97     x=++tot,tag[x]=-1,sz1[x]=b-a+1;
     98     if(a==b){
     99         if(mp[st[a]]==0)tag[x]=2;else
    100         if(mp[st[a]]==1)mx0[x]=1,tag[x]=0;else
    101         if(mp[st[a]]==2)mx1[x]=1,tag[x]=1;else
    102         tag[x]=3;
    103 //      printf("build:  %d  %d
    ",st[a],mp[st[a]]);
    104         return;
    105     }
    106     int mid=a+b>>1;
    107     build(lc[x],a,mid),build(rc[x],mid+1,b);
    108     upd(x);
    109 }
    110 int dfs(int x){
    111     if(x>n)return mp[x];
    112     int i;sz[x]=1;
    113     for(i=last[x];i;i=e[i].pre)mp[x]+=dfs(e[i].too),sz[x]+=sz[e[i].too];
    114     return mp[x]>1;
    115 }
    116 void dfs2(int x,int chain){
    117     bel[x]=chain;int i,mx=0;
    118     dfn[x]=++tim,st[++top]=x,
    119     pos[x]=dfn[x]-dfn[chain]+1;//printf("dfs2:  x:%d   bel:%d  pos:%d
    ",x,chain,pos[x]);
    120     for(i=last[x];i;i=e[i].pre)
    121         if(sz[e[i].too]>sz[mx])mx=e[i].too;
    122     if(!mx){
    123         len[chain]=top,build(rt[chain],1,top),top=0;
    124         return;
    125     }
    126     dfs2(mx,chain);
    127     for(i=last[x];i;i=e[i].pre)
    128         if(e[i].too!=mx)dfs2(e[i].too,e[i].too);
    129 }
    130  
    131 inline void run(int x){
    132     bool flag=!mp[x];int num1;//printf("    fa:%d  add:%d
    ",fa[x],flag);
    133     mp[x]^=1,x=fa[x];
    134     if(flag){
    135         while(1){
    136             LEN=0,R=pos[x],query0(rt[bel[x]],1,len[bel[x]]);//printf("LEN:  %d
    ",LEN);
    137             LEN=pos[x]-LEN;
    138             if(LEN>0){add1(rt[bel[x]],1,len[bel[x]]);break;}
    139             else if(bel[x]==1){ans=1;break;}
    140             else x=fa[bel[x]];
    141         }
    142     }
    143     else{
    144         while(1){
    145             LEN=0,R=pos[x],query1(rt[bel[x]],1,len[bel[x]]);//printf("LEN:  %d
    ",LEN);
    146             LEN=pos[x]-LEN;
    147             if(LEN>0){add0(rt[bel[x]],1,len[bel[x]]);break;}
    148             else if(bel[x]==1){ans=0;break;}
    149             else x=fa[bel[x]];
    150         }
    151     }
    152 }
    153  
    154 inline void insert(int a,int b){
    155     if(b<=n)
    156         e[++tot1].too=b,e[tot1].pre=last[a],last[a]=tot1;
    157     fa[b]=a;
    158 }
    159 int main(){
    160     n=read();
    161     for(i=1;i<=n;i++)insert(i,read()),insert(i,read()),insert(i,read());
    162     for(i=n+1;i<=3*n+1;i++)mp[i]=read(),mp[fa[i]]+=mp[i];
    163     ans=dfs(1);dfs2(1,1);//printf("ans:  %d
    ",ans);
    164     m=read();
    165     while(m--)
    166         run(read()),
    167         puts(ans?"1":"0");
    168     return 0;
    169 }
    View Code
  • 相关阅读:
    leetcode 1. 两数之和
    leetcode 671. 二叉树中第二小的节点
    leetcode 100. 相同的树
    leetcode 110. 平衡二叉树
    leetcode 144. 二叉树的前序遍历
    1066. Root of AVL Tree (25)
    leetcode 100 相同的树
    leeCode 515 在每个树行中找最大值
    LeetCode 31.下一个排列
    面向对象UML中类关系
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5597966.html
Copyright © 2020-2023  润新知