[破碎的状态] [-16] 100960 H
感谢@似水流年 翻译..
n个点,要求强制在线(交互):
1(C),连接两点
2(D),删除某两点之间的连边
3(T),问两点是否有边相连
4(E),结束程序
=================
特殊条件:
1,一共会调用n-1次C,这n-1次C好像会把整个图连接成一颗树
2,一共会调用n-1次D
3,n<=100000,总询问数<=300000
实际上..
这题可以直接LCT..
我就当LCT练手题了..
没特判x==y被WA了好久好难过...
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<time.h> #include<math.h> #include<memory> #include<vector> #include<bitset> #include<fstream> #include<stdio.h> #include<utility> #include<sstream> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; struct node { bool rev_tag; node * father; node * ch[2]; }; node * null; node * new_node() { static node a[100005]; static int top=0; node * t=&a[top++]; t->father=null; t->ch[0]=null; t->ch[1]=null; t->rev_tag=false; return t; } void rotate(node * &x,int c) { node * y=x->ch[c]; x->ch[c]=y->ch[!c]; y->ch[!c]->father=x; y->ch[!c]=x; y->father=x->father; x->father=y; x=y; } void push_down(node * &x) { if (x->rev_tag) { swap(x->ch[0],x->ch[1]); x->ch[0]->rev_tag^=1; x->ch[1]->rev_tag^=1; x->rev_tag=false; } } int get_up(node * x) { if (x->father->ch[0]==x) return 0; if (x->father->ch[1]==x) return 1; return -1; } void splay(node * &x) { for (;;) { push_down(x->father->father); push_down(x->father); push_down(x); int t1=get_up(x); if (t1==-1) return; int t2=get_up(x->father); if (t2==-1) { x=x->father; rotate(x,t1); } else { int t3=get_up(x->father->father); if (t3!=-1) { if (t1==t2) { x=x->father; x=x->father; x=x->father; rotate(x->ch[t3],t2); rotate(x->ch[t3],t1); x=x->ch[t3]; } else { x=x->father; x=x->father; rotate(x->ch[t2],t1); x=x->father; rotate(x->ch[t3],t2); x=x->ch[t3]; } } else { if (t1==t2) { x=x->father; x=x->father; rotate(x,t2); rotate(x,t1); } else { x=x->father; x=x->father; rotate(x->ch[t2],t1); rotate(x,t2); } } } } } void access(node * &x) { for (;;) { splay(x); if (x->father==null) { x->ch[1]=null; return; } splay(x->father); x->father->ch[1]=x; } } void evert(node * &x) { access(x); x->rev_tag^=1; } void link(node * x,node * y) { evert(x); x->father=y; } void cut(node * x,node * y) { evert(x); access(y); y->ch[0]->father=null; y->ch[0]=null; } node * a[100005]; int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int n; scanf("%d",&n); int i; null=new_node(); null->father=null; null->ch[0]=null; null->ch[1]=null; for (i=0;i<n;i++) { a[i]=new_node(); } for (;;) { static char c[15]; scanf("%s",c); if (c[0]=='C') { int x,y; scanf("%d%d",&x,&y); x--; y--; link(a[x],a[y]); } else if (c[0]=='D') { int x,y; scanf("%d%d",&x,&y); x--; y--; cut(a[x],a[y]); } else if (c[0]=='T') { int x,y; scanf("%d%d",&x,&y); x--; y--; evert(a[x]); access(a[y]); if ((a[x]->father!=null)||(x==y)) { puts("YES"); } else { puts("NO"); } fflush(stdout); } else { break; } } return 0; }