zoukankan      html  css  js  c++  java
  • CF165D Beard Graph

    $ color{#0066ff}{ 题目描述 }$

    给定一棵树,有m次操作。

    1 x 把第x条边染成黑色

    2 x 把第x条边染成白色

    3 x y 查询x~y之间的黑边数,存在白边输出-1

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

    第一行一个正整数N (1 ≤ N ≤ 100000),节点总数

    接下来N − 1行,每行两个整数a,b 表示一条边

    接下来是一个正整数m(1 ≤ m ≤ 300000),表示共有m次操作。

    后面跟着m行,是操作

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

    对于每一个询问,输出一行答案

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

    3
    1 2
    2 3
    7
    3 1 2
    3 1 3
    3 2 3
    2 2
    3 1 2
    3 1 3
    3 2 3
    
        
    6
    1 5
    6 4
    2 3
    3 5
    5 6
    6
    3 3 4
    2 5
    3 2 6
    3 1 2
    2 3
    3 3 1
    

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

    1
    2
    1
    1
    -1
    -1
    
        
    3
    -1
    3
    2
    

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

    none

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

    只有两种颜色,维护两个LCT就行了

    LCT上维护siz,询问时siz-1就是答案

    无解就是不联通qwq

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL 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 + 10;
    struct LCT {
    protected:
    	struct node {
    		node *ch[2], *fa;
    		int siz, rev;
    		node(int siz = 0, int rev = 0): siz(siz), rev(rev) {
    			fa = ch[0] = ch[1] = NULL;
    		}
    		void trn() { std::swap(ch[0], ch[1]), rev ^= 1; }
    		void dwn() {
    			if(!rev) return;
    			if(ch[0]) ch[0]->trn();
    			if(ch[1]) ch[1]->trn();
    			rev = 0;
    		}
    		void upd() { siz = (ch[0]? ch[0]->siz : 0) + (ch[1]? ch[1]->siz : 0) + 1; }
    		bool isr() { return fa->ch[1] == this; }
    		bool ntr() { return fa && (fa->ch[1] == this || fa->ch[0] == this); }
    	}pool[maxn];
    	void rot(node *x) {
    		node *y = x->fa, *z = y->fa;
    		bool k = x->isr(); node *w = x->ch[!k];
    		if(y->ntr()) z->ch[y->isr()] = x;
    		(x->ch[!k] = y)->ch[k] = w;
    		(y->fa = x)->fa = z;
    		if(w) w->fa = y;
    		y->upd(), x->upd();
    	}
    	void splay(node *o) {
    		static node *st[maxn];
    		int top;
    		st[top = 1] = o;
    		while(st[top]->ntr()) st[top + 1] = st[top]->fa, top++;
    		while(top) st[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, x->upd();
    	}
    	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 x;
    	}
    public:
    	void link(int l, int r) {
    		node *x = pool + l, *y = pool + r;
    		makeroot(x), x->fa = y;
    	}
    	void cut(int l, int r) {
    		node *x = pool + l, *y = pool + r;
    		makeroot(x), access(y), splay(y);
    		if(y->ch[0] == x) y->ch[0] = x->fa = NULL;
    	}
    	int query(int l, int r) {
    		node *x = pool + l, *y = pool + r;
    		if(findroot(x) != findroot(y)) return -1;
    		makeroot(x), access(y), splay(y);
    		return y->siz - 1;
    	}
    }s[2];
    std::pair<int, int> mp[maxn];
    int col[maxn];
    int main() {
    	int n = in();
    	for(int i = 1; i < n; i++) s[1].link(mp[i].first = in(), mp[i].second = in()), col[i] = 1;
    	int x, y, p;
    	for(int T = in(); T --> 0;) {
    		p = in();
    		if(p == 1) {
    			if(col[x = in()]) continue;
    			s[0].cut(mp[x].first, mp[x].second);
    			s[col[x] = 1].link(mp[x].first, mp[x].second);
    		}
    		if(p == 2) {
    			if(!col[x = in()]) continue;
    			s[1].cut(mp[x].first, mp[x].second);
    			s[col[x] = 0].link(mp[x].first, mp[x].second);
    		}
    		if(p == 3) x = in(), y = in(), printf("%d
    ", s[1].query(x, y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    iOS drewRect方法
    iOS中的单例
    iOS中类别的使用
    iOS存储的三种方式
    安卓上微信闪退的一种解决方法
    [Z] 通天塔导游:各种编程语言的优缺点
    怎样面对痛苦?
    [Z] 10 种必知必会的软件开发工具
    [Z] Linux 内核同步机制
    [Z] 囚禁你的精灵(daemon)进程
  • 原文地址:https://www.cnblogs.com/olinr/p/10458625.html
Copyright © 2011-2022 走看看