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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值