数组,至少目前我只写数组,不写指针。
LCT这种东西我不打算讲或者什么乱七八糟的,反正这一篇是自用。
同样,看这篇博客的人可以先去别的地方学LCT,然后来我这扒代码。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define ls son[x][0] #define rs son[x][1] #define is(x) (x==son[fa[x]][1]) #define isroot(x) (x!=son[fa[x]][0]&&x!=son[fa[x]][1]) #define N 10010 #define inf 0x3f3f3f3f using namespace std; int pos[N],n,m; char ttt[10]; struct LCT { int son[N][2],fa[N],cnt; bool flag[N]; int stack[N],top; void joint(int x,int y,int d){fa[x]=y,son[y][d]=x;} void reverse(int x) { flag[x]^=1; swap(ls,rs); } void pushdown(int x) { if(flag[x]) { reverse(x); flag[ls]^=1,flag[rs]^=1; flag[0]=0; } } int newnode() { cnt++; son[cnt][0]=son[cnt][1]=fa[cnt]=0; return cnt; } void pushpath(int x) { for(top=0;!isroot(x);x=fa[x])stack[++top]=x; stack[++top]=x; for(int i=top;i;i--)pushdown(stack[i]); } void rotate(int x) { int y=fa[x],z=fa[y],i=is(x),t=son[x][!i]; if(!isroot(y))joint(x,z,is(y)); else fa[x]=z; joint(t,y,i),joint(y,x,!i); fa[0]=son[0][0]=son[0][1]=0; } void splay(int x) { pushpath(x); int y,z; while(!isroot(x)) { y=fa[x],z=fa[y]; if(isroot(y)){rotate(x);break;} rotate(is(x)==is(y)?y:x),rotate(x); } } void access(int x) { int p=0; while(x) { splay(x); rs=p,p=x,x=fa[x]; } } void makeroot(int x) { access(x); splay(x); flag[x]=1; pushdown(x); } void link(int x,int y) { makeroot(x); fa[x]=y; } void cut(int x,int y) { makeroot(y); access(x); splay(x); ls=fa[y]=0; } int findroot(int x) { while(fa[x])x=fa[x]; return x; } }lct; int main() { // freopen("test.in","r",stdin); int i,a,b; scanf("%d%d",&n,&m); for(i=1;i<=n;i++)pos[i]=lct.newnode(); for(i=1;i<=m;i++) { scanf("%s",ttt); scanf("%d%d",&a,&b); if(ttt[0]=='C')lct.link(pos[a],pos[b]); else if(ttt[0]=='D')lct.cut(pos[a],pos[b]); else { if(lct.findroot(pos[a])==lct.findroot(pos[b]))puts("Yes"); else puts("No"); } } return 0; }
【BZOJ2049】【SDOI2008】Cave 洞穴勘测 LCT裸题 模版题 数组版
原文地址:http://blog.csdn.net/vmurder/article/details/41483027