就不发题意了...
LCT模板题,和http://www.spoj.com/problems/DYNACON1/一样,但是不卡常数。
并查集做法见:http://blog.youkuaiyun.com/braketbn/article/details/50733104
数组:
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int n, m, son[maxn][2], pre[maxn];
bool rev[maxn];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline bool isroot(int x) {
return son[pre[x]][0] != x && son[pre[x]][1] != x;
}
inline void pushdown(int x) {
if(rev[x]) {
rev[son[x][0]] ^= 1; rev[son[x][1]] ^= 1;
swap(son[x][0], son[x][1]);
rev[x] = 0;
}
}
int sta[maxn];
inline void maintain(int x) {
int top = 0;
for(sta[++top] = x; !isroot(x); x = pre[x]) sta[++top] = pre[x];
for(; top; pushdown(sta[top--]));
}
inline void rotate(int x) {
int y = pre[x], z = pre[y], type = son[y][1] == x;
pre[son[y][type] = son[x][!type]] = y;
pre[x] = z;
if(!isroot(y)) son[z][son[z][1] == y] = x;
pre[son[x][!type] = y] = x;
}
inline void splay(int x) {
maintain(x);
while(!isroot(x)) {
int y = pre[x], z = pre[y];
if(isroot(y)) rotate(x);
else if(son[z][1] == y ^ son[y][1] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
}
inline void access(int x) {
for(int y = 0; x; x = pre[y = x]) {
splay(x);
son[x][1] = y;
}
}
inline void makeroot(int x) {
access(x); splay(x); rev[x] ^= 1;
}
inline int findroot(int x) {
access(x); splay(x);
for(; son[x][0]; x = son[x][0]);
return x;
}
inline void link(int a, int b) {
makeroot(a); pre[a] = b;
}
inline void cut(int a, int b) {
makeroot(a); access(b); splay(b);
son[b][0] = pre[a] = 0;
}
inline bool check(int a, int b) {
if(findroot(a) == findroot(b)) return 1;
return 0;
}
int main() {
n = iread(); m = iread();
while(m--) {
char ch = getchar(); for(; ch != 'C' && ch != 'D' && ch != 'Q'; ch = getchar());
int a = iread(), b = iread();
if(ch == 'C') link(a, b);
else if(ch == 'D') cut(a, b);
else printf(check(a, b) ? "Yes\n" : "No\n");
}
return 0;
}
指针:
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int n, m;
struct node {
node *son[2], *pre;
bool rev;
} pool[maxn], *null;
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline bool isroot(node *x) {
return x->pre->son[0] != x && x->pre->son[1] != x;
}
inline void pushdown(node *x) {
if(x->rev) {
x->son[0]->rev ^= 1; x->son[1]->rev ^= 1;
swap(x->son[0], x->son[1]);
x->rev = 0;
}
}
node *sta[maxn];
inline void maintain(node *x) {
int top = 0;
for(sta[++top] = x; !isroot(x); x = x->pre) sta[++top] = x->pre;
for(; top; pushdown(sta[top--]));
}
inline void rotate(node *x) {
node *y = x->pre, *z = y->pre; int type = y->son[1] == x;
y->son[type] = x->son[!type];
x->son[!type]->pre = y;
x->pre = z;
if(!isroot(y)) z->son[z->son[1] == y] = x;
x->son[!type] = y;
y->pre = x;
}
inline void splay(node *x) {
maintain(x);
while(!isroot(x)) {
node *y = x->pre, *z = y->pre;
if(isroot(y)) rotate(x);
else if(z->son[1] == y ^ y->son[1] == x) rotate(x), rotate(x);
else rotate(y), rotate(x);
}
}
inline void access(node *x) {
for(node *y = null; x != null; x = x->pre) {
splay(x);
x->son[1] = y;
y = x;
}
}
inline void makeroot(node *x) {
access(x); splay(x); x->rev ^= 1;
}
inline node* findroot(node* x) {
access(x); splay(x);
for(; x->son[0] != null; x = x->son[0]);
return x;
}
inline void link(int x, int y) {
node *a = pool + x, *b = pool + y;
makeroot(a); a->pre = b;
}
inline void cut(int x, int y) {
node *a = pool + x, *b = pool + y;
makeroot(a); access(b); splay(b);
b->son[0] = a->pre = pool;
}
inline bool check(int x, int y) {
node *a = pool + x, *b = pool + y;
if(findroot(a) == findroot(b)) return 1;
return 0;
}
int main() {
n = iread(); m = iread();
null = pool; null->son[0] = null->son[1] = null->pre = null; null->rev = 0;
for(int i = 1; i <= n; i++) {
node *x = pool + i;
x->son[0] = x->son[1] = x->pre = null;
x->rev = 0;
}
while(m--) {
char ch = getchar(); for(; ch != 'C' && ch != 'D' && ch != 'Q'; ch = getchar());
int a = iread(), b = iread();
if(ch == 'C') link(a, b);
else if(ch == 'D') cut(a, b);
else printf(check(a, b) ? "Yes\n" : "No\n");
}
return 0;
}