原题地址:P4312 [COCI 2009] OTOCI / 极地旅行社/SP4155 OTOCI - OTOCI
lct入门难度的题,十分弱智(小蒟蒻说lct是什么,能吃吗?)
bridge操作判联通,用find,不同的话link一下
penguins修改点权,把这个点旋转到树根暴力修改并pushup
excursion先判联通,如果联通输出点权之和
操作就是这样,简单有点像P2147 [SDOI2008]洞穴勘测
代码:
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 300005
using namespace std;
inline int read()
{
int f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
inline void Swap(register int &a,register int &b)
{
a^=b^=a^=b;
}
int n,m,v[N];
struct Link_cut_tree{
int top,c[N][2],fa[N],q[N],rev[N],sum[N];
inline void pushup(register int x)
{
sum[x]=sum[c[x][0]]+sum[c[x][1]]+v[x];
}
inline void pushdown(int x)
{
int l=c[x][0],r=c[x][1];
if(rev[x])
{
rev[l]^=1;
rev[r]^=1;
rev[x]^=1;
Swap(c[x][0],c[x][1]);
}
}
inline bool isroot(int x)
{
return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
}
inline void rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(c[y][0]==x)
l=0;
else
l=1;
r=l^1;
if(!isroot(y))
{
if(c[z][0]==y)
c[z][0]=x;
else
c[z][1]=x;
}
fa[x]=z;
fa[y]=x;
fa[c[x][r]]=y;
c[y][l]=c[x][r];
c[x][r]=y;
pushup(y);
pushup(x);
}
inline void splay(int x)
{
top=1;
q[top]=x;
for(register int i=x;!isroot(i);i=fa[i])
q[++top]=fa[i];
for(register int i=top;i;--i)
pushdown(q[i]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if((c[y][0]==x)^(c[z][0]==y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
pushup(x);
}
inline void access(int x)
{
for(register int t=0;x;t=x,x=fa[x])
{
splay(x);
c[x][1]=t;
pushup(x);
}
}
inline void makeroot(int x)
{
access(x);
splay(x);
rev[x]^=1;
}
inline int find(int x)
{
access(x);
splay(x);
while(c[x][0])
x=c[x][0];
return x;
}
inline void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
}
inline void cut(int x,int y)
{
split(x,y);
if(c[y][0]==x)
{
c[y][0]=0;
fa[x]=0;
}
}
inline void link(int x,int y)
{
makeroot(x);
fa[x]=y;
}
}T;
int main()
{
n=read();
for(register int i=1;i<=n;++i)
{
v[i]=read();
T.sum[i]=v[i];
}
m=read();
while(m--)
{
char c[10];
scanf("%s",c);
int x=read(),y=read();
if(c[0]=='b')
{
if(T.find(x)==T.find(y))
puts("no");
else
{
puts("yes");
T.link(x,y);
}
}
else if(c[0]=='p')
{
T.access(x);
T.splay(x);
v[x]=y;
T.pushup(x);
}
else
{
if(T.find(x)!=T.find(y))
puts("impossible");
else
{
T.split(x,y);
printf("%d
",T.sum[y]);
}
}
}
return 0;
}
lct真简单