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 ",lastans); } }
代码中ima维护了虚边信息