poj 2777 Count Color (線段樹)
阿新 • • 發佈:2021-07-13
題目連結:http://poj.org/problem?id=2777
顏色數量很少,所以狀壓進 \(int\),線段樹維護即可
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn = 100010; int n, T, m; struct Node{ int tag; int color; }t[maxn << 2]; void pushup(int i){ t[i].color = (t[i << 1].color | t[i << 1 | 1].color); } void pushdown(int i, int l, int r){ if(t[i].tag != -1){ t[i << 1].tag = t[i << 1 | 1].tag = t[i].tag; t[i << 1].color = t[i].color; t[i << 1 | 1].color = t[i].color; t[i].tag = -1; } } void build(int i, int l, int r){ t[i].tag = -1; if(l == r){ t[i].color = 1; t[i].tag = -1; return; } int mid = (l + r) >> 1; build(i << 1, l, mid); build(i << 1 | 1, mid + 1, r); pushup(i); } void modify(int i, int c, int l, int r, int x, int y){ if(x <= l && r <= y){ t[i].color = 0; t[i].tag = c; t[i].color = (1 << c); return; } pushdown(i, l, r); int mid = (l + r) >> 1; if(x <= mid) modify(i << 1, c, l, mid, x, y); if(y > mid) modify(i << 1 | 1, c, mid + 1, r, x, y); pushup(i); } int query(int i, int l, int r, int x, int y){ if(x <= l && r <= y){ return t[i].color; } pushdown(i, l, r); int color = 0; int mid = (l + r) >> 1; if(x <= mid) color |= query(i << 1, l, mid, x, y); if(y > mid) color |= query(i << 1 | 1, mid + 1, r, x, y); return color; } int count(int x){ int res = 0; while(x){ if(x & 1) ++res; x >>= 1; } return res; } ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ scanf("%d%d%d", &n, &T, &m); --T; build(1, 1, n); char op[10]; int a, b, c; for(int i = 1 ; i <= m ; ++i){ scanf("%s", op); if(op[0] == 'C'){ scanf("%d%d%d", &a, &b, &c); if(a > b) swap(a, b); --c; modify(1, c, 1, n, a, b); } else{ scanf("%d%d", &a, &b); if(a > b) swap(a, b); int C = query(1, 1, n, a, b); printf("%d\n", count(query(1, 1, n, a, b))); } } return 0; }