[破碎的状态] [-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;
}
评论 (0)