题目链接:http://poj.org/problem?id=2777
题意:给定长度L的区间,初始全部为1。
两种操作
1. 更新:C A B C 将区间[A,B]全部赋值为C。
2. 查询:P A B 查询区间[A,B]的颜色种数。
思路:基本为裸的区间更新。
因为最多只有30种颜色,所以在存储某个区间的颜色类型和种数时,可以利用一个int数来存储(利用每一位的二进制,1为有该颜色,0位无该颜色)。
代码:
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
const int N = 1e5 + 5;
const int INF = 1e9 + 10;
const double EPS = 1e-6;
int board[N << 2];
int lazy[N << 2];
void pushup(int rt) {
board[rt] = board[rt << 1] | board[rt << 1 | 1];
}
void pushdown(int rt) {
if (lazy[rt] != -1) {
lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
board[rt << 1] = lazy[rt];
board[rt << 1 | 1] = lazy[rt];
lazy[rt] = -1;
}
}
void build(int l, int r, int rt) {
lazy[rt] = -1;
if (l == r) {
board[rt] = 1;
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int c, int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
board[rt] = c;
lazy[rt] = c;
return ;
}
pushdown(rt);
int m = (l + r) >> 1;
if (L <= m)
update(c, L, R, lson);
if (R > m)
update(c, L, R, rson);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return board[rt];
}
pushdown(rt);
int m = (l + r) >> 1;
int ql = 0, qr = 0, res;
if (L <= m)
ql = query(L, R, lson);
if (R > m)
qr = query(L, R, rson);
res = ql | qr;
pushup(rt);
return res;
}
int main() {
int L, T, O;
while (scanf("%d%d%d", &L, &T, &O) != EOF) {
build(1, L, 1);
for (int i_q = 1; i_q <= O; i_q++) {
char str[2];
int l, r;
scanf("%s%d%d", str, &l, &r);
if (l > r)
swap(l, r);
if (str[0] == ‘C‘) {
int c;
scanf("%d", &c);
c = (1 << (c - 1));
update(c, l, r, 1, L, 1);
}
else {
int res = query(l, r, 1, L, 1);
int co = 0;
while (res) {
if (res & 1)
co++;
res >>= 1;
}
printf("%d\n", co);
}
}
cout << endl;
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014357885/article/details/47090327