poj2777(线段树)
Count Color
思路:暴力能过,线段树维护这个区间的颜色,如果是混色则置为1,如果是单一颜色则设为这个颜色,修改就是正常的区间修改,区间查询就要变一下。还有题解是用二进制做得,可以学一下。
#define _CRT_SECURE_NO_WARNINGS 1
#include<algorithm>
#include<fstream>
#include<iostream>
#include<cstdio>
#include<deque>
#include<string>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
//#include<unordered_map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 310000
#define N 210100
#define endl '\n'
#define exp 1e-8
#define lc p << 1
#define rc p << 1|1
#define lowbit(x) ((x)&-(x))
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
inline LL read() {
ULL x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
struct tree
{
int l, r,v,tag; //v代表颜色,tag是标记
}tr[4 * N];
int n, t, m;
int ha[50];
void pushup(int p)
{
if (tr[lc].v == tr[rc].v) //如果左右区间颜色一样,则为一样
tr[p].v = tr[lc].v;
else tr[p].v = 0; //否则置为0
}
void pushdown(int p) //标记下传
{
if (tr[p].tag)
{
tr[lc].v = tr[rc].v = tr[p].tag;
tr[lc].tag = tr[rc].tag = tr[p].tag;
tr[p].tag = 0;
}
}
void build(int p, int l, int r)
{
tr[p].l = l, tr[p].r = r;
if (l == r) { tr[p].v = 1; return; }
int m = l + r >> 1;
build(lc, l, m);
build(rc, m + 1, r);
pushup(p);
}
void update(int p, int x, int y, int k)
{
if (tr[p].v == k)return; //一个小小的剪枝,当要修改的区间颜色就是c时,直接返回不用修改
if (x <= tr[p].l && tr[p].r <= y)
{
tr[p].v = k;
tr[p].tag = k;
return;
}
pushdown(p);
int m = tr[p].l + tr[p].r >> 1;
if (x <= m)update(lc, x, y, k);
if (y > m)update(rc, x, y, k);
pushup(p);
}
void query(int p, int x, int y)
{
if (tr[p].v!=0) //如果不为0,则表示为纯色
{
if (x <= tr[p].l && tr[p].r <= y)
{
ha[tr[p].v] = 1;
return;
}
}
pushdown(p);
int m = tr[p].l + tr[p].r >> 1; //为0就分裂
if (x <= m) query(lc, x, y);
if (y > m) query(rc, x, y);
}
int main()
{
n = read(), t = read(), m = read();
build(1, 1, n);
for (int i = 1; i <= m; i++)
{
char a;
cin >> a;
if (a == 'C')
{
int x, y, c;
x = read(), y = read(), c = read();
if (x > y)swap(x, y);
update(1, x, y, c);
}
else if(a=='P')
{
int x, y;
x = read(), y = read();
if (x > y)swap(x, y);
int ans = 0;
memset(ha, 0, sizeof(ha));
query(1, x, y);
for (int i = 1; i <= 40; i++)
{
if (ha[i])ans++;
}
printf("%d\n", ans);
}
}
return 0;
}