码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2011]染色

时间:2020-03-04 09:35:53      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:algo   csharp   vector   http   png   wap   tree   www   lse   

很神仙的题

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\n", ask(x, y));
		}
		else {
			scanf("%d %d %d", &be, &en, &val);
			upadd(be, en, val); 
		}
	}
	return 0;
}

  

[SDOI2011]染色

标签:algo   csharp   vector   http   png   wap   tree   www   lse   

原文地址:https://www.cnblogs.com/lesning/p/12406170.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!