LCT

  int isroot(int po){
      return(po!=tr[tr[po].fa].son[0]&&po!=tr[tr[po].fa].son[1]);
  }
  
  void pushdown(int po){
      if (tr[po].rev){
        swap(tr[po].son[0],tr[po].son[1]);
      tr[tr[po].son[0]].rev^=1;tr[tr[po].son[1]].rev^=1;
      tr[po].rev=0;    
    }
  }
  
  void update(int po){
      pushdown(po);
      tr[po].size=tr[tr[po].son[0]].size+tr[tr[po].son[1]].size+1;
  }
  
  void rotate(int po,int dir){
      pushdown(po);pushdown(tr[po].son[0]);pushdown(tr[po].son[1]);
      int so=tr[po].son[dir];
      tr[so].fa=tr[po].fa;
      if (po==tr[tr[po].fa].son[0]) tr[tr[po].fa].son[0]=so;else
      if (po==tr[tr[po].fa].son[1]) tr[tr[po].fa].son[1]=so;
      tr[po].fa=so;
      tr[po].son[dir]=tr[so].son[dir^1];
      if (tr[so].son[dir^1]){
        tr[tr[so].son[dir^1]].fa=po;
    }
    tr[so].son[dir^1]=po;
    update(po);update(so);
  }
  
  void relax(int po){
      if (!isroot(po)) relax(tr[po].fa);
      pushdown(po);
  }
  
  void splay(int po){
      relax(po);
      
      if (isroot(po)) return;
      while (!isroot(po)){
        if (isroot(tr[po].fa)){
          rotate(tr[po].fa,(po==tr[tr[po].fa].son[1]));
          continue;
      }
      
      int u,v;
      if (po==tr[tr[po].fa].son[1]) u=1;else u=-1;
      if (tr[po].fa==tr[tr[tr[po].fa].fa].son[1]) v=1;else v=-1;
      if (u*v==1){
          rotate(tr[tr[po].fa].fa,tr[po].fa==tr[tr[tr[po].fa].fa].son[1]);
          rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
      }else{
          rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
          rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
      }
    }
  }
  
  void access(int po){
      int last=0;
      while (po){
      splay(po);
        tr[po].son[1]=last;
        if (last) tr[last].fa=po;
      update(po);
      last=po;
      po=tr[po].fa;    
    }
  }

  void makeroot(int po){
      access(po);
    splay(po);
    tr[po].rev^=1;
  }

  void link(int x,int y){
      makeroot(x);
    tr[x].fa=y;
  }
  
  int getdis(int x,int y){
      if (x==1&&y==3){
        x++;x--;    
    }
      makeroot(x);
    access(y);
    splay(y);
    return(tr[y].size-1);
  }

 ________________________________________________________________________

LCT可以额外维护一个节点虚边所连的信息。这样LCT就可以维护子树中有加减性的信息(如权值和)

#include <cstdio>
#include <iostream>
using namespace std;

struct treenode{
  int fa,son[2],size,dp[2][2],ima[2];
}tr[600001];

int isroot(int po) {
  return(po!=tr[tr[po].fa].son[0]&&po!=tr[tr[po].fa].son[1]);
}

void update(int po) {
  tr[po].size=tr[tr[po].son[0]].size+tr[tr[po].son[1]].size+1;
  int tmax[2][2];tmax[0][0]=tmax[0][1]=tmax[1][0]=tmax[1][1]=0;
  for (int i=0;i<2;i++)
    for (int j=0;j<2;j++){
      tmax[i|(!tr[po].son[0])][j|(!tr[po].son[1])]=tr[tr[po].son[0]].dp[i][0]+tr[tr[po].son[1]].dp[0][j]+tr[po].ima[0]+1;    
      tmax[i][j]=max(tmax[i][j],max(tr[tr[po].son[0]].dp[i][0],tr[tr[po].son[0]].dp[i][1])+max(tr[tr[po].son[1]].dp[0][j],tr[tr[po].son[1]].dp[1][j])+tr[po].ima[1]);
    }
  for (int i=0;i<2;i++) for (int j=0;j<2;j++) tr[po].dp[i][j]=tmax[i][j];
}

void rotate(int po,int dir) {
  int so=tr[po].son[dir];
  tr[so].fa=tr[po].fa;
  if (po==tr[tr[po].fa].son[0]) tr[tr[po].fa].son[0]=so;
  else if (po==tr[tr[po].fa].son[1]) tr[tr[po].fa].son[1]=so;
  tr[po].fa=so;
  tr[po].son[dir]=tr[so].son[dir^1];
  if (tr[so].son[dir^1]) {
    tr[tr[so].son[dir^1]].fa=po;
  }
  tr[so].son[dir^1]=po;
  update(po);
  update(so);
}

void relax(int po) {
  if (!isroot(po)) relax(tr[po].fa);
}

void splay(int po) {
  relax(po);

  if (isroot(po)) return;
  while (!isroot(po)) {
    if (isroot(tr[po].fa)) {
      rotate(tr[po].fa,(po==tr[tr[po].fa].son[1]));
      continue;
    }

    int u,v;
    if (po==tr[tr[po].fa].son[1]) u=1;
    else u=-1;
    if (tr[po].fa==tr[tr[tr[po].fa].fa].son[1]) v=1;
    else v=-1;
    if (u*v==1) {
      rotate(tr[tr[po].fa].fa,tr[po].fa==tr[tr[tr[po].fa].fa].son[1]);
      rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
    } else {
      rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
      rotate(tr[po].fa,po==tr[tr[po].fa].son[1]);
    }
  }
}

void access(int po) {
  int last=0;
  while (po){
    splay(po);
      tr[po].ima[0]+=max(tr[tr[po].son[1]].dp[0][0],tr[tr[po].son[1]].dp[0][1]);
    tr[po].ima[1]+=max(max(tr[tr[po].son[1]].dp[0][0],tr[tr[po].son[1]].dp[0][1]),max(tr[tr[po].son[1]].dp[1][0],tr[tr[po].son[1]].dp[1][1]));
    
    tr[po].son[1]=last;
    
    tr[po].ima[0]-=max(tr[last].dp[0][0],tr[last].dp[0][1]);
    tr[po].ima[1]-=max(max(tr[last].dp[0][0],tr[last].dp[0][1]),max(tr[last].dp[1][0],tr[last].dp[1][1]));
    
    if (last) tr[last].fa=po;
    update(po);
    last=po;
    po=tr[po].fa;
  }
}

void ins(int po,int tar){
  access(tar);splay(tar);
  tr[po].fa=tar;
  tr[tar].ima[0]+=max(tr[po].dp[0][0],tr[po].dp[0][1]);
  tr[tar].ima[1]+=max(max(tr[po].dp[0][0],tr[po].dp[0][1]),max(tr[po].dp[1][0],tr[po].dp[1][1]));
  update(tar);
}

int main() {
  int n,typ;
  scanf("%d%d",&n,&typ);
  int lastans=0;
  for (int i=2;i<=n+1;i++){
      int f;
      scanf("%d",&f);if (typ) f^=lastans;f++;
    tr[i].dp[0][0]=tr[i].dp[0][1]=tr[i].dp[1][0]=0;tr[i].dp[1][1]=1;
    ins(i,f);
    
    access(1);splay(1);
    lastans=max(max(tr[1].dp[0][0],tr[1].dp[0][1]),max(tr[1].dp[1][0],tr[1].dp[1][1]));
    printf("%d\n",lastans);
  }
}

代码中ima维护了虚边信息

posted @ 2017-03-16 14:17  z1j1n1  阅读(226)  评论(0编辑  收藏  举报