pku 2777 Count Color

也是线段树经典题,不过做了好久...
这道题与之前的3468最大的区别在于它需要在递归前根据情况更新子节点的值,也就是
		if (count(tree[node]) == 1)
			tree[node * 2] = tree[node * 2 + 1] = tree[node];


#include <cstdio>
#include <algorithm>
using std::swap;

const int maxL = 100000 + 5;
int L, T, O, tree[maxL * 3] = {0};

int count(int x)
{
	int cnt = 0;
	while (x)
		++cnt, x -= x & -x;
	return cnt;
}

int A, B, C, color;
void add(int low, int high, int node)
{
	if (A <= low && high <= B) {
		tree[node] = color;
	} else if (low <= B && A <= high) {
		if (count(tree[node]) == 1)
			tree[node * 2] = tree[node * 2 + 1] = tree[node];
		int mid = (low + high) / 2;
		add(low, mid, node * 2);
		add(mid + 1, high, node * 2 + 1);
		tree[node] = tree[node * 2] | tree[node * 2 + 1];
	}
}

int query(int low, int high, int node)
{
	if (A <= low && high <= B) {
		return tree[node];
	} else if (low <= B && A <= high) {
		if (count(tree[node]) == 1)
			tree[node * 2] = tree[node * 2 + 1] = tree[node];
		int mid = (low + high) / 2;
		return query(low, mid, node * 2) | query(mid + 1, high, node * 2 + 1);
	}
	return 0;
}

int main()
{
	char op;
	scanf("%d%d%d", &L, &T, &O);
	for (int i = 1; i <= L; ++i)
	{
		A = B = i, color = 1;
		add(1, L, 1);
	}
	for (int i = 0; i < O; ++i)
	{
		scanf(" %c", &op);
		scanf("%d%d", &A, &B);
		if (A > B)
			swap(A, B);
		if (op == 'C') {
			scanf("%d", &C);
			color = 1 << (C - 1);
			add(1, L, 1);
		} else {
			printf("%d\n", count(query(1, L, 1)));
		}
	}
	return 0;
}

你可能感兴趣的:(C++,c,C#)