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;
}

猜你喜欢

转载自www.cnblogs.com/Narh/p/9239469.html
今日推荐