zoukankan      html  css  js  c++  java
  • SP8791 DYNALCA

    (color{#0066ff}{ 题目描述 })

    有一个森林最初由 n ((1 le n le 100000))n((1leq nleq 100000)) 个互不相连的点构成

    你需要处理以下操作:

    link A B:添加从顶点A到B的边,使A成为B的子节点,其中保证A是一个根顶点,A和B在不同的树中。

    cut A:切断点A到其父节点的边,保证A是一个非根节点。

    lca A B:输出A和B的最近共同祖先,保证A和B在同一棵树中。

    (color{#0066ff}{输入格式})

    第一行包含三个正整数N、M,分别表示树的结点个数、询问的个数

    接下来M行表示询问。

    (color{#0066ff}{输出格式})

    对于每个LCA询问输出答案

    (color{#0066ff}{输入样例})

    5 9
    lca 1 1
    link 1 2
    link 3 2
    link 4 3
    lca 1 4
    lca 3 4
    cut 4
    link 5 3
    lca 1 5
    

    (color{#0066ff}{输出样例})

    1
    2
    3
    2
    

    (color{#0066ff}{数据范围与提示})

    none

    (color{#0066ff}{ 题解 })

    LCT求LCA

    cut的时候,因为删的是父子边,暴力找前驱就行了

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    LL in() {
    	char ch; int x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int maxn = 1e5 + 5;
    struct LCT {
    protected:
    	struct node {
    		node *ch[2], *fa;
    		int rev;
    		node(int rev = 0): rev(rev) { ch[0] = ch[1] = fa = NULL; }
    		bool ntr() { return fa && (fa->ch[1] == this || fa->ch[0] == this); }
    		bool isr() { return fa->ch[1] == this; }
    		void trn() { std::swap(ch[0], ch[1]); rev ^= 1; }
    		void dwn() { if(rev) { if(ch[0]) ch[0]->trn(); if(ch[1]) ch[1]->trn(); rev = 0; } }
    	}s[maxn], *lst, *t[maxn];
    	int top, fa[maxn];
    	void rot(node *x) {
    		node *y = x->fa, *z = y->fa; int k = x->isr(); node *w = x->ch[!k];
    		if(y->ntr()) z->ch[y->isr()] = x;
    		x->ch[!k] = y, y->ch[k] = w;
    		y->fa = x, x->fa = z;
    		if(w) w->fa = y;
    	}
    	void splay(node *o) {
    		t[top = 1] = o;
    		while(t[top]->ntr()) t[top + 1] = t[top]->fa, top++;
    		while(top) t[top--]->dwn();
    		while(o->ntr()) { if(o->fa->ntr()) rot(o->isr() ^ o->fa->isr()? o : o->fa); rot(o); }
    	}
    	void access(node *x) { for(node *y = NULL; x; x = (y = x)->fa) splay(x), x->ch[1] = y, lst = x; }
    	void makeroot(node *x) { access(x), splay(x), x->trn(); }
    	node *findroot(node *x) { 
    		access(x), splay(x); 
    		while(x->dwn(), x->ch[0]) x = x->ch[0]; 
    		return splay(x), x;
    	}
    	void link(node *x, node *y) { makeroot(x), x->fa = y; }
    	node *pre(node *x) { 
    		access(x), splay(x); x->dwn(), x = x->ch[0]; 
    		while(x->dwn(), x->ch[1]) x = x->ch[1]; 
    		return splay(x), x;
    	}
    	void cut(node *x) {
    		access(x), splay(x), x->dwn();
    		node *y = x->ch[0];
    		while(y->dwn(), y->ch[1]) y = y->ch[1];
    		splay(y);
    		y->ch[1] = x->fa = NULL;
    	}
    public:
    	int LCA(int x, int y) { return access(s + x), access(s + y), lst - s; }
    	void link(int x, int y) { link(s + x, s + y); }
    	void cut(int x) { cut(s + x); }
    }v;
    char getch() {
    	char ch;
    	while(!isalpha(ch = getchar()));
    	return ch;
    }
    int main() {
    	int n = in(), m = in();
    	int x, y;
    	while(m --> 0) {
    		if(getch() == 'l') {
    			if(getch() == 'c') x = in(), y = in(), printf("%d
    ", v.LCA(x, y));
    			else x = in(), y = in(), v.link(x, y);
    		}
    		else v.cut(in());
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python基础-字符串方法 、文件操作
    Python基础-列表、字典
    Python基础作业-用户登录
    LeetCode 78. Subsets
    LeetCode 77. Combinations
    LeetCode 76. Minimum Window Substring
    LeetCode 74. Search a 2D Matrix
    LeetCode 73. Set Matrix Zeroes
    LightOJ 1043
    LightOJ 1042
  • 原文地址:https://www.cnblogs.com/olinr/p/10258593.html
Copyright © 2011-2022 走看看