[Data structures] --SHOI2014 trigeminal tree

The first black to write questions, so nervous (bushi)


 

(Pictures cut from the Los Valley)

  This question can be said to be a practiced hand LCT's title, the first title given to the tree, if we change the value of a leaf node, then the scope of its parent, if the parent node is changed, then the node may also grandfather It will change, so we guess, whether for a chain of change exist?

  Obviously, if a node represents a state with 0/1/2/3, i.e., the son comprises a number of digits, then for a period of from shallow to deep 1/0/1/1/0, node 0 becomes a deepest for one, the sequence will become: 1/1/2/2/1, shallow affect up to that node 0.

  If you take into account the changes from 1 to 0, in fact, is a reason, (where the chain is 2) Therefore, we consider maintaining some bottom-up range to meet contain a contiguous 1/2, 1/2 not until the emergence of a the point, then modify the interval, and then modify the point alone, the maintenance is complete.

  Specifically, let's open up the subject to the point x, open up the path, and then look for the deepest node that is not 1/2, modify some tips:

  1. multiplied by 2 leaf nodes, branches equal to the sum divided by two leaf nodes, can be very convenient.

  Step 2. Update upward: Because splay maintenance of depth, so right -> yourself -> left order the best were a judgment.

  3. The step down transmission: the essence of each interval becomes 1 2,2 to 1, the exclusive OR value to 3, while the exchange of maintaining the array num1 x, num2 (because this time period 1 2 sequence will all be changed, while maintaining some tantamount to a sequence 2 )

  4. Note cards often, the inline register int ah ah, what quick read are open, straight down to 200ms time from 4.2s.

  5. I was miserable pit memory, will open a variety of normal size WA, RE, MLE what, it was opened a few times, all changed TLE, after the opening size of the array according to the requirements of the subject as much as possible to open a large point .

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define rs c[x][1]
  4 #define ls c[x][0]
  5 const int N=2e6+5;
  6 int n;
  7 int f[N],cnt,sum[N],q,tot,head[N],aa,bb,cc,ans;
  8 int c[N][2],st[N],num2[N],num1[N],tag[N];
  9 inline int read()
 10 {
 11    int ans = 0,op = 1;char ch = getchar();
 12    while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
 13    while(ch >='0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
 14    return ans * op;
 15 }
 16 struct edge{
 17     int next,to;
 18 }e[N<<1];
 19 void addedge(int from,int to){
 20     e[++cnt].to=to;
 21     e[cnt].next=head[from];
 22     head[from]=cnt;
 23 }
 24 void dfs(int u){
 25     for(int i=head[u];i;i=e[i].next){
 26         dfs(e[i].to);
 27         sum[u]+=(sum[e[i].to]>>1);
 28     }
 29 }
 30 int nroot(int x){
 31     return c[f[x]][0]==x||c[f[x]][1]==x;
 32 }
 33 void pushup(int x){
 34     num1[x]=num1[rs];
 35     if(!num1[x]&&sum[x]!=1) num1[x]=x;
 36     if(!num1[x]) num1[x]=num1[ls];
 37     num2[x]=num2[rs];
 38     if(!num2[x]&&sum[x]!=2) num2[x]=x;
 39     if(!num2[x]) num2[x]=num2[ls];
 40 }
 41 void pusm(int x,int d){
 42     sum[x]^=3;
 43     swap(num1[x],num2[x]);
 44     tag[x]+=d;
 45 }
 46 void pushdown(int x){
 47     if(nroot(x)) pushdown(f[x]);
 48     if(tag[x]){
 49         pusm(ls,tag[x]);
 50         pusm(rs,tag[x]);
 51         tag[x]=0;
 52     } 
 53 }
 54 void rotate(int x){
 55     int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][k^1];
 56     if(nroot(y)) c[z][c[z][1]==y]=x; 
 57     c[x][k^1]=y;
 58     c[y][k]=w;
 59     if(w) f[w]=y;
 60     f[y]=x;
 61     f[x]=z;
 62     pushup(y);
 63     
 64 }
 65 void splay(int x){
 66     pushdown(x);
 67     int y=x,z=0;
 68     st[++z]=y;
 69     while(nroot(y)) st[++z]=y=f[y];
 70     while(z) pushdown(st[z--]);
 71     while(nroot(x)){
 72         y=f[x],z=f[y];
 73         if(nroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?x:y);
 74         rotate(x);
 75     }
 76     pushup(x);
 77 }
 78 void access(int x){
 79     for(int g=0;x;x=f[g=x]){
 80         splay(x);
 81         rs=g;
 82         pushup(x);
 83     }
 84 }
 85 int main(){
 86 //    freopen("neuron.in","r",stdin);
 87 //    freopen("neuron.out","w",stdout);
 88     n=read();
 89     int i;
 90     for(i=1;i<=n;i++){
 91         aa=read(),bb=read(),cc=read();
 92         f[aa]=f[bb]=f[cc]=i;
 93         addedge(i,aa);
 94         addedge(i,bb);
 95         addedge(i,cc);
 96     }
 97     for(;i<=3*n+1;i++){
 98         aa=read();
 99         sum[i]=(aa<<1);
100     }
101     dfs(1);
102     q=read();
103     ans=sum[1]>>1;
104     for(i=1;i<=q;i++){
105         aa=read();
106         sum[aa]^=2;//单点修改
107         int k=sum[aa]-1; 
108         aa=f[aa];
109         access(aa);
110         splay(aa);//将区间的端点旋转到根 
111         int p=(~k)?num1[aa]:num2[aa];//找到最深的非1或2点 
112         if(!p) pusm(aa,k),pushup(aa),ans^=1;//如果这个点不存在,说明就是原树根了 
113         else{
114             splay(p);//这个时候aa点已经在p的右子树了 
115             pusm(c[p][1],k);
116             pushup(c[p][1]);
117             sum[p]+=k;
118             pushup(p);
119         }
120         printf("%d\n",ans);
121     }
122     return 0;
123 }

 

 

 

  

 

Guess you like

Origin www.cnblogs.com/Nelson992770019/p/11333198.html