• [SDOI2011]染色


    很神仙的题

    https://www.luogu.com.cn/problem/P2486

    大致如下图,我感觉本质还是数据结构线段树。

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn = 1e5 + 70;
    #define L (node<<1)  
    #define R (node<<1|1)  
    int n, m;
    int head[maxn];
    int cnn = 0;
    struct no {
    	int to;
    	int next;
    }G[maxn * 2];
    
    void add(int be, int en) {
    	G[++cnn].to = en;
    	G[cnn].next = head[be];
    	head[be] = cnn;
    }
    int f[maxn], siz[maxn], son[maxn], dep[maxn], Lc, Rc;
    int id[maxn], top[maxn];
    int dfs1(int x, int fa, int d) {
    	f[x] = fa;
    	dep[x] = d;
    	siz[x] = 1;
    	int s = 0;
    	for (int i = head[x]; i; i = G[i].next) {
    		int p = G[i].to;
    		if (p == fa) continue;
    		dfs1(p, x, d + 1);
    		siz[x] += siz[p];
    		if (siz[p] > s) {
    			s = siz[p];
    			son[x] = p;
    		}
    	}
    	return 0;
    }
    int cn = 0;
    int dfs2(int x, int c) {
    
    	id[x] = ++cn;
    	top[x] = c;
    	if (son[x]) dfs2(son[x], c);
    
    	for (int i = head[x]; i; i = G[i].next) {
    		int p = G[i].to;
    		if (p == f[x] || p == son[x]) continue;
    		dfs2(p, p);
    	}
    	return 0;
    }
    int list[maxn];
    struct Node {
    	int l, r;
    	int lc, rc;
    	int flag, num;
    }tree[1000000];
    void push_up(int node) {
    	int l = node * 2;
    	int r = node * 2 + 1;
    	tree[node].num = tree[l].num + tree[r].num;
    	if (tree[l].rc == tree[r].lc) tree[node].num--;
    	tree[node].lc = tree[l].lc;
    	tree[node].rc = tree[r].rc;
    }
    void push(int node,int clor) {
    	tree[node].lc = tree[node].rc = clor;
    	tree[node].flag = 1;
    	tree[node].num = 1;
    }
    
    void push_down(int node) {
    	int l = node * 2;
    	int r = node * 2 + 1;
    	if (tree[node].flag) {
    		tree[node].flag = 0;
    
    		tree[l].flag = tree[r].flag = 1;
    		tree[l].num = tree[r].num = 1;
    		tree[l].lc = tree[l].rc = tree[node].lc;
    		tree[r].lc = tree[r].rc = tree[node].rc;
    	}
    	return;
    }
    void bulit(int node, int be, int en){
    
    
    	tree[node].l = be;
    	tree[node].r = en;
    	if (be == en) {
    		return;
    	}
    	int mid = (be + en) / 2;
    	bulit(L, be, mid);
    	bulit(R, mid + 1, en);
    }
    int update(int node, int LL, int RR, int val) {
    	int l = node * 2;
    	int r = node * 2 + 1;
    	if (LL <= tree[node].l && tree[node].r <= RR) {
    		push(node, val);
    		return 0;
    	}
    	int mid = (tree[node].l + tree[node].r) / 2;
    	push_down(node);
    	if (LL <= mid) update(l,LL, RR, val);
    	if (RR > mid) update(r, LL, RR, val);
    	push_up(node);
    }
    
    int qurry(int node, int LL, int RR) {
    	int l = node * 2;
    	int r = node * 2 + 1;
    	int mid = (tree[node].l + tree[node].r) / 2;
    	if (LL <= tree[node].l && tree[node].r <= RR) {
    		if (LL == tree[node].l) Lc = tree[node].lc;
    		if (RR == tree[node].r) Rc = tree[node].rc;
    		return tree[node].num;
    	}
    
    	push_down(node);
    	if (RR <= mid) {
    		return qurry(l, LL, RR);
    	}
    	else if (LL > mid) {
    		return qurry(r, LL, RR);
    	}
    	else {
    		int ans = qurry(l, LL, RR) + qurry(r, LL, RR);
    		if (tree[l].rc == tree[r].lc) ans--;
    		return ans;
    	}
    }
    int upadd(int x, int y, int val) {
    	while (top[x]!= top[y]) {
    		if (dep[top[x]] < dep[top[y]]) swap(x, y);
    		update(1, id[top[x]], id[x], val);
    		x = f[top[x]];
    	}
    	if (dep[x] > dep[y]) swap(x, y);
    	update(1, id[x], id[y], val);
    	return 0;
    }
    
    
    int ask(int x, int y) {
    	int ans1 = 0;
    	int ans2 = 0;
    	int ans = 0;
    	while (top[x] != top[y]) {
    		if (dep[top[x]] < dep[top[y]]) {
    			swap(x, y);
    			swap(ans1, ans2);
    		}
    		ans += qurry(1, id[top[x]], id[x]);
    		if (Rc == ans1) ans--;
    		x = f[top[x]];
    		ans1 = Lc;
    	}
    	if (dep[x] > dep[y]) {
    		swap(x, y);
    		swap(ans1, ans2);
    	}
    	ans += qurry(1, id[x], id[y]);
    	if (Lc == ans1) ans--;
    	if (Rc == ans2) ans--;
    	return ans;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &list[i]);
    	}
    
    	int be, en;
    	for (int i = 0; i < n - 1; i++) {
    		scanf("%d%d", &be, &en);
    		add(be, en);
    		add(en, be);
    	}
    	dfs1(1, -1, 0);
    	dfs2(1, 1);
    	bulit(1, 1, n);
    	for (int i = 1; i <= n; i++) {
    		update(1, id[i], id[i], list[i]);
    	}
    	int val;
    	while (m--) {
    		char s[10];
    		scanf("%s", s);
    		if (s[0] == 'Q') {
    			int x, y;
    			scanf("%d %d", &x, &y);
    			printf("%d
    ", ask(x, y));
    		}
    		else {
    			scanf("%d %d %d", &be, &en, &val);
    			upadd(be, en, val); 
    		}
    	}
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    Python 实现红绿灯
    ELK使用1-Elasticsearch使用
    CF Educational Codeforces Round 21
    Codeforces Round #408 (Div. 2)
    2017年 湘潭邀请赛(湖南)or 江苏省赛
    Tinkoff Challenge
    欧几里德算法与扩展欧几里德算法
    operator的各种问题
    树状数组 Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains
    Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) D. Field expansion
  • 原文地址:https://www.cnblogs.com/lesning/p/12406170.html
Copyright © 2020-2023  润新知