题目大意:给出一些初始相互分离的岛,有三个操作,1.分析两点是否联通,如果不连通,在之间连一条边。2.更改一个点的权值。3.询问两点之间路径上所有点的点权和。
思路:基本算是LCT的模板题了吧,好久没写了,基本都要忘了,这是照别人代码写的。。。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 30010 using namespace std; struct SplayTree{ SplayTree *son[2],*father; int val,sum; bool reverse; SplayTree(int _); bool Check() { return father->son[1] == this; } void Reverse() { reverse ^= 1; swap(son[0],son[1]); } void PushUp(); void PushDown(); }none(0),*nil = &none,*tree[MAX]; SplayTree:: SplayTree(int _) { val = sum = _; reverse = false; son[0] = son[1] = father = nil; } void SplayTree:: PushDown() { if(father->son[0] == this || father->son[1] == this) father->PushDown(); if(reverse) { son[0]->Reverse(); son[1]->Reverse(); reverse = false; } } void SplayTree:: PushUp() { sum = son[0]->sum + son[1]->sum + val; } int points,asks; char s[20]; inline void Rotate(SplayTree *a,bool dir) { SplayTree *f = a->father; f->son[!dir] = a->son[dir]; f->son[!dir]->father = f; a->son[dir] = f; a->father = f->father; if(f->father->son[0] == f || f->father->son[1] == f) f->father->son[f->Check()] = a; f->father = a; f->PushUp(); } inline void Splay(SplayTree *a) { a->PushDown(); while(a->father->son[0] == a || a->father->son[1] == a) { SplayTree *f = a->father; if(f->father->son[0] != f && f->father->son[1] != f) Rotate(a,!a->Check()); else if(!f->Check()) { if(!a->Check()) Rotate(f,true),Rotate(a,true); else Rotate(a,false),Rotate(a,true); } else { if(a->Check()) Rotate(f,false),Rotate(a,false); else Rotate(a,true),Rotate(a,false); } } a->PushUp(); } inline void Access(SplayTree *a) { SplayTree *temp = nil; while(a != nil) { Splay(a); a->son[1] = temp; a->PushUp(); temp = a; a = a->father; } } inline SplayTree *Find(SplayTree *a) { while(a->father != nil) a = a->father; return a; } inline void ToRoot(SplayTree *a) { Access(a); Splay(a); a->Reverse(); } inline void Link(SplayTree *x,SplayTree *y) { ToRoot(x); x->father = y; } int main() { cin >> points; for(int x,i = 1; i <= points; ++i) { scanf("%d",&x); tree[i] = new SplayTree(x); } cin >> asks; for(int x,y,i = 1; i <= asks; ++i) { scanf("%s%d%d",s,&x,&y); if(s[0] == 'b') { SplayTree *fx = Find(tree[x]); SplayTree *fy = Find(tree[y]); if(fx == fy) puts("no"); else { puts("yes"); Link(tree[x],tree[y]); } } else if(s[0] == 'p') { Splay(tree[x]); tree[x]->val = y; tree[x]->PushUp(); } else { SplayTree *fx = Find(tree[x]); SplayTree *fy = Find(tree[y]); if(fx != fy) puts("impossible"); else { ToRoot(tree[x]); Access(tree[y]); Splay(tree[y]); printf("%d\n",tree[y]->sum); } } } return 0; }
时间: 2024-11-05 13:45:02