Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define INF (1<<30)
- using namespace std;
- int id_cnt = 0; // Each Node has a unique ID (for debugging purpouses)
- struct Node{
- Node *left, *right, *parent;
- Node *thin_parent;
- bool rotated;
- int value;
- int size;
- int subtree_min;
- int lazy_add;
- int id;
- Node(int v = 0): left(0), right(0), parent(0), thin_parent(0), rotated(false), value(v), size(1), subtree_min(v), lazy_add(0){
- id = id_cnt++;
- }
- };
- bool is_left_child(Node *n){
- assert(n->parent);
- return n->parent->left == n;
- }
- void set_parent(Node *n, Node *p){
- if(!n)return;
- n->parent = p;
- }
- // Propagates lazy flags
- void touch(Node *n){
- if(!n)return;
- if(n->rotated){
- swap(n->left, n->right);
- if(n->left)n->left->rotated = !n->left->rotated;
- if(n->right)n->right->rotated = !n->right->rotated;
- n->rotated = false;
- }
- if(n->lazy_add != 0){
- int a = n->lazy_add;
- if(n->left){
- n->left->lazy_add+=a;
- n->left->value+=a;
- n->left->subtree_min+=a;
- }
- if(n->right){
- n->right->lazy_add+=a;
- n->right->value+=a;
- n->right->subtree_min+=a;
- }
- n->lazy_add=0;
- }
- }
- int size(Node *n){
- return n ? n->size : 0;
- }
- int subtree_min(Node *n){
- return n ? n->subtree_min : INF;
- }
- void soak(Node *n){
- n->size = 1 + size(n->left) + size(n->right);
- n->subtree_min = min(n->value, min(subtree_min(n->left), subtree_min(n->right)));
- }
- Node * splay(Node *n){
- assert(n);
- stack<Node*> s;
- Node *l_root = new Node;
- Node *r_root = new Node;
- Node *l = l_root, *r = r_root;
- Node *x = n;
- while(x->parent){
- s.push(x);
- x = x->parent;
- }
- Node *thin_parent = x->thin_parent;
- x->thin_parent = NULL;
- Node *y, *z;
- while(!s.empty()){
- y = s.top();
- s.pop();
- touch(x);
- touch(y);
- if(s.empty()){ // There was only one vertex remaining
- if(is_left_child(y)){
- r->left = x;
- set_parent(x, r);
- r = x;
- } else{
- l->right = x;
- set_parent(x, l);
- l = x;
- }
- x = y;
- x->parent=NULL;
- break;
- }
- z = s.top();
- s.pop();
- touch(z);
- if(is_left_child(y) && is_left_child(z)){
- Node *tmp = y->right;
- x->left = tmp;
- set_parent(tmp, x);
- y->left = NULL;
- y->right = x;
- set_parent(x, y);
- r->left = y;
- set_parent(y, r);
- soak(x);
- r = y;
- x = z;
- } else if(!is_left_child(y) && !is_left_child(z)){
- Node *tmp = y->left;
- x->right = tmp;
- set_parent(tmp, x);
- y->right = NULL;
- y->left = x;
- set_parent(x, y);
- l->right = y;
- set_parent(y, l);
- soak(x);
- l = y;
- x = z;
- } else if(is_left_child(y) && !is_left_child(z)){
- s.push(z);
- r->left = x;
- set_parent(x, r);
- x->left = NULL;
- r = x;
- x = y;
- } else /*if(!is_left_child(y) && is_left_child(z))*/{
- s.push(z);
- l->right = x;
- set_parent(x, l);
- x->right = NULL;
- l = x;
- x = y;
- }
- x->parent=NULL;
- }
- touch(x);
- Node *A = x->left, *B = x->right;
- l->right = A;
- set_parent(A, l);
- while(l){
- soak(l);
- l = l->parent;
- }
- r->left = B;
- set_parent(B, r);
- while(r){
- soak(r);
- r = r->parent;
- }
- x->left = l_root->right;
- set_parent(x->left, x);
- x->right = r_root->left;
- set_parent(x->right, x);
- soak(x);
- x->thin_parent = thin_parent;
- assert(x == n);
- delete l_root;
- delete r_root;
- return x;
- }
- Node * join(Node *l, Node *r){
- if(!l)return r;
- if(!r)return l;
- while(l->parent)l = l->parent;
- touch(l);
- while(l->right){
- l = l->right;
- touch(l);
- }
- splay(l);
- splay(r);
- l->right = r;
- set_parent(r, l);
- soak(l);
- return l;
- }
- Node * prev(Node *n){
- splay(n);
- if(!n->left)return 0;
- n=n->left;
- touch(n);
- while(n->right){
- n=n->right;
- touch(n);
- }
- return splay(n);
- }
- Node * next(Node *n){
- splay(n);
- if(!n->right)return 0;
- n=n->right;
- touch(n);
- while(n->left){
- n=n->left;
- touch(n);
- }
- return splay(n);
- }
- Node * first(Node *n){
- assert(n);
- while(n->parent)n=n->parent;
- touch(n);
- while(n->left){
- n=n->left;
- touch(n);
- }
- return splay(n);
- }
- Node * last(Node *n){
- assert(n);
- while(n->parent)n=n->parent;
- touch(n);
- while(n->right){
- n=n->right;
- touch(n);
- }
- return splay(n);
- }
- pair<Node*, Node*> path_cut_before(Node *n){
- splay(n);
- Node *l = n->left;
- set_parent(l, 0);
- n->left=0;
- soak(n);
- return make_pair(l, n);
- }
- pair<Node*, Node*> path_cut(Node *n){
- splay(n);
- Node *r = n->right;
- set_parent(r, 0);
- r->thin_parent = n->thin_parent;
- n->thin_parent = 0;
- n->right=0;
- soak(n);
- return make_pair(n, r);
- }
- void path_link(Node *a, Node *b){
- splay(a); splay(b);
- Node *thin_parent = b->thin_parent;
- b->thin_parent = NULL;
- Node *tmp = join(a, b);
- tmp->thin_parent = thin_parent;
- }
- void reverse(Node *n){
- auto tmp = path_cut_before(n);
- tmp.second->rotated=!tmp.second->rotated;
- join(tmp.first, tmp.second);
- }
- int cost(Node *n){
- return splay(n)->value;
- }
- int path_min(Node *n){
- splay(n);
- return min(n->value, subtree_min(n->right));
- }
- void set_cost(Node *n, int cost){
- splay(n);
- n->value = cost;
- soak(n);
- }
- void path_update(Node *n, int delta){
- auto tmp = path_cut_before(n);
- tmp.second->value+=delta;
- tmp.second->subtree_min+=delta;
- tmp.second->lazy_add+=delta;
- join(tmp.first, tmp.second);
- }
- Node *parent(Node *n){
- splay(n);
- Node *x = next(n);
- if(x)return splay(x);
- return n->thin_parent ? splay(n->thin_parent) : 0;
- }
- Node *root(Node *n){
- n = last(n);
- while(n->thin_parent){
- n = n->thin_parent;
- n = last(n);
- }
- return splay(n);
- }
- void cut(Node *n){
- if(next(n)){
- path_cut(n);
- } else{
- splay(n);
- n->thin_parent=0;
- }
- }
- void link(Node *u, Node *v){
- splay(u);
- u->thin_parent = v;
- }
- void expose(Node *n){
- auto tmp = path_cut_before(n);
- if(tmp.first)tmp.first->thin_parent=n;
- splay(n);
- Node *p;
- while(n->thin_parent){
- p=n->thin_parent;
- n->thin_parent=0;
- tmp = path_cut_before(p);
- if(tmp.first)tmp.first->thin_parent=p;
- path_link(n, p);
- n=splay(p);
- }
- }
- void evert(Node *n){
- expose(n);
- splay(n);
- n->rotated = !n->rotated;
- }
- Node *nodes[111111];
- int n, m, a, b;
- int main(){
- scanf("%d %d", &n, &m);
- nodes[0] = NULL;
- for (int i = 1; i <= n; ++i) {
- nodes[i] = new Node(i);
- nodes[i]->thin_parent = nodes[i];
- }
- for (int i = 1; i <= m; ++i) {
- string s;
- cin >> s;
- scanf("%d %d", &a, &b);
- if(s[1]=='o'){ // connected
- printf(root(nodes[a]) == root(nodes[b]) ? "1\n" : "0\n");
- }
- if(s[1]=='u'){ // cut
- evert(nodes[a]);
- assert(parent(nodes[b]) == nodes[a]);
- cut(nodes[b]);
- }
- if(s[1]=='i'){ // link
- evert(nodes[a]);
- assert(root(nodes[b]) != root(nodes[a]));
- link(nodes[a], nodes[b]);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement