from popoqqq 指针版
BZOJ 2049洞穴勘测
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
node *fa,*lc,*rc;
bool rev;
node();
void pushdown();
}*null=new node,tree[10010];
node::node()
{
fa=lc=rc=null;
}
void node::pushdown()
{
if(fa->lc==this||fa->rc==this)
fa->pushdown();
if(rev)
{
lc->rev^=1;
rc->rev^=1;
swap(lc,rc);
rev=0;
}
}
void zig(node*x)
{
node*y=x->fa,*z=y->fa;
y->lc=x->rc;
x->rc->fa=y;
x->rc=y;
y->fa=x;
if(z->lc==y)z->lc=x;
else if(z->rc==y)z->rc=x;
x->fa=z;
}
void zag(node*x)
{
node*y=x->fa,*z=y->fa;
y->rc=x->lc;
x->lc->fa=y;
x->lc=y;
y->fa=x;
if(z->lc==y)z->lc=x;
else if(z->rc==y)z->rc=x;
x->fa=z;
}
void splay(node*x)
{
x->pushdown();
while(x->fa->lc==x||x->fa->rc==x)
{
node*y=x->fa,*z=y->fa;
if(x==y->lc)
{
if(y==z->lc)zig(y);
zig(x);
}
else
{
if(y==z->rc)zag(y);
zag(x);
}
}
}
void access(node*x)
{
node*y=null;
while(x!=null)
{
splay(x);
x->rc=y;
y=x;
x=x->fa;
}
}
void toroot(node*x)
{
access(x);
splay(x);
x->rev^=1;
x->pushdown();
}
void query(node*x,node*y)
{
access(x);
splay(x);
while(y->fa!=null)
y=y->fa;
if(y==x)puts("Yes");
else puts("No");
}
void link(node*x,node*y)
{
toroot(x);
x->fa=y;
}
void cut(node*x,node*y)
{
toroot(x);
access(y);
splay(y);
y->lc=null;
x->fa=null;
}
int n,m;
char op[7];
int main()
{
null->fa=null->lc=null->rc=null;
scanf("%d%d",&n,&m);
for(int i=1,x,y;i<=m;++i)
{
scanf("%s%d%d",op,&x,&y);
if(op[0]=='Q')query(&tree[x],&tree[y]);
else if(op[0]=='C')link(&tree[x],&tree[y]);
else cut(&tree[x],&tree[y]);
}
}
数组版(更简单)
SPOJ GSS7 Can you answer these queries VII
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,cnt,fa[100010],ch[100010][2],key[100010],lx[100010],rx[100010],mx[100010],sum[100010],sz[100010];
bool rt[100010],tag[100010],rev[100010];
void pushup(int x)
{
int l=ch[x][0],r=ch[x][1];
sz[x]=sz[l]+sz[r]+1;
sum[x]=sum[l]+sum[r]+key[x];
lx[x]=max(0,max(lx[l],sum[l]+key[x]+lx[r]));
rx[x]=max(0,max(rx[r],sum[r]+key[x]+rx[l]));
mx[x]=max(0,max(max(mx[l],mx[r]),max(0,rx[l])+key[x]+max(0,lx[r])));
}
void setv(int x,int w)
{
if(x==0)return;
key[x]=w;
sum[x]=sz[x]*w;
mx[x]=lx[x]=rx[x]=max(0,sum[x]);
tag[x]=1;
}
void reverse(int x)
{
swap(ch[x][0],ch[x][1]);
swap(lx[x],rx[x]);
rev[x]^=1;
}
void pushdown(int x)
{
if(!rt[x])pushdown(fa[x]);
if(tag[x])
{
setv(ch[x][0],key[x]);
setv(ch[x][1],key[x]);
tag[x]=0;
}
if(rev[x])
{
reverse(ch[x][0]);
reverse(ch[x][1]);
rev[x]=0;
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y];
bool f=ch[y][1]==x;
ch[y][f]=ch[x][!f];
fa[ch[y][f]]=y;
ch[x][!f]=y;
fa[ch[x][!f]]=x;
fa[x]=z;
if(rt[y])rt[y]=0,rt[x]=1;
else ch[z][y==ch[z][1]]=x;
pushup(y);
}
void splay(int x)
{
pushdown(x);
for(int y,z;!rt[x];rotate(x))
{
y=fa[x],z=fa[y];
if(!rt[y])
{
if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
else rotate(y);
}
}
pushup(x);
}
void access(int x)
{
for(int y=0;x;y=x,x=fa[x])
{
splay(x);
rt[ch[x][1]]=1;
ch[x][1]=y;
rt[ch[x][1]]=0;
pushup(x);
}
}
void toroot(int x)
{
access(x);
splay(x);
reverse(x);
}
void link(int x,int y)
{
toroot(x);
fa[x]=y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&key[i]);
sum[i]=key[i];
sz[i]=1;
lx[i]=rx[i]=mx[i]=max(0,key[i]);
rt[i]=1;
}
for(int i=1,u,v;i<n;++i)
{
scanf("%d%d",&u,&v);
link(u,v);
}
scanf("%d",&m);
for(int i=1,op,u,v,c;i<=m;++i)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&u,&v);
toroot(u);
access(v);
splay(v);
printf("%d\n",mx[v]);
}
else
{
scanf("%d%d%d",&u,&v,&c);
toroot(u);
access(v);
splay(v);
setv(v,c);
pushdown(v);
}
}
}