bzoj 1036 [ZJOI2008]树的统计Count
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1036
水到不行的LCT模板。
需要注意读入val之后再link,才能pshp上。
十分需要注意把mx[0]弄成-30005。唉,这个还是看了TJ。但改了就A了还是好高兴。
主要是在emacs上写的,故缩进可能有点奇怪。而且在emacs上为什么不能运行?似乎是using、int之类的找不到指令?
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=3e4+5; int n,q,val[N],pre[N],sum[N],mx[N],c[N][2],stack[N],top,xx[N],yy[N]; bool rev[N]; bool isroot(int x){return ((c[pre[x]][0]!=x)&&(c[pre[x]][1]!=x));} void reverse(int x) { if(rev[x]) { rev[c[x][0]]^=1;rev[c[x][1]]^=1; swap(c[x][0],c[x][1]); rev[x]=0; } } void pshp(int x) { int ls=c[x][0],rs=c[x][1]; mx[x]=max(val[x],max(mx[ls],mx[rs])); sum[x]=sum[ls]+sum[rs]+val[x]; } void rotate(int x) { int y=pre[x],z=pre[y],d=(x==c[y][1]); if(!isroot(y))c[z][y==c[z][1]]=x; pre[x]=z;pre[y]=x; c[y][d]=c[x][!d];pre[c[x][!d]]=y;c[x][!d]=y; pshp(y);pshp(x); } void splay(int x) { stack[top=1]=x; for(int t=x;!isroot(t);t=pre[t])stack[++top]=pre[t]; for(;top;top--)reverse(stack[top]); for(;!isroot(x);rotate(x)) { int y=pre[x],z=pre[y]; if(isroot(y))continue; ((x==c[y][0])^(y==c[z][0]))?rotate(x):rotate(y); } } void access(int x) { for(int t=0;x;c[x][1]=t,pshp(x),t=x,x=pre[x])splay(x); } void makeroot(int x) { access(x);splay(x);rev[x]^=1; } void query(int x,int y) { makeroot(x);access(y);splay(y); } void link(int x,int y) { makeroot(x);pre[x]=y; } int main() { scanf("%d",&n);int x,y;mx[0]=-30005;// for(int i=1;i<n;i++)scanf("%d%d",&xx[i],&yy[i]); for(int i=1;i<=n;i++)scanf("%d",&val[i]); for(int i=1;i<n;i++)link(xx[i],yy[i]); scanf("%d",&q); char ch[10]; for(int i=1;i<=q;i++) { scanf("%s%d%d",ch,&x,&y); if(ch[1]=='H'){ makeroot(x); val[x]=y;pshp(x); } if(ch[1]=='M'){ query(x,y);printf("%d\n",mx[y]); } if(ch[1]=='S'){ query(x,y);printf("%d\n",sum[y]); } } return 0; }