动态树裸题,直接放代码
/************************************************************** PRoblem: 2049 User: vermouth Language: C++ Result: Accepted Time:2188 ms Memory:1724 kb****************************************************************/ #include<cstdio>#include<iostream>using namespace std;const int maxn=21000;int n,m,x,y,sz[maxn],fa[maxn],tree[maxn][2],s[maxn];bool rev[maxn];bool isroot(int x){ return tree[fa[x]][0]!=x&&tree[fa[x]][1]!=x;}inline void pushup(int x){ sz[x]=sz[tree[x][0]]+sz[tree[x][1]]+1;}inline void pushdown(int x){ if(rev[x]) { rev[x]^=1;rev[tree[x][0]]^=1;rev[tree[x][1]]^=1; swap(tree[x][0],tree[x][1]); }}void rotate(int x){ int y=fa[x],z=fa[y],l=tree[y][1]==x,r=l^1; if(!isroot(y)) tree[z][tree[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[tree[x][r]]=y; tree[y][l]=tree[x][r];tree[x][r]=y; pushup(y);pushup(x);}void splay(int x){ int top=0;s[++top]=x; for(int i=x;!isroot(i);i=fa[i]) { s[++top]=fa[i]; } for(int i=top;i;i--) pushdown(s[i]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(tree[y][0]==x^tree[z][0]==y) rotate(y);else rotate(x); } rotate(x); }}void access(int x){ int t=0; while(x) { splay(x); tree[x][1]=t; t=x;x=fa[x]; }}void rever(int x){ access(x);splay(x);rev[x]^=1; }void link(int x,int y){ rever(x);fa[x]=y;splay(x); } void cut(int x,int y){ rever(x);access(y);splay(y);tree[y][0]=fa[x]=0;}int find(int x){ access(x);splay(x); int y=x; while(tree[y][0]) y=tree[y][0]; return y;}char op[10];int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%s",op); scanf("%d%d",&x,&y); if(op[0]=='C') link(x,y); else if(op[0]=='Q') { if(find(x)==find(y)) puts("Yes");else puts("No"); } else if(op[0]=='D') cut(x,y); } return 0;}/*200 5Query 123 127Connect 123 127Query 123 127Destroy 127 123Query 123 127*/新闻热点
疑难解答