poj2777--Count Color(線段樹&&二進位制)
阿新 • • 發佈:2018-12-15
連結:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100005; struct Segment { int l,r; int status;//染色情況 int cover;//lazy_tag }tree[maxn<<2]; int n,color,m; void build(int rt,int l,int r) { tree[rt].l = l, tree[rt].r = r; tree[rt].status = tree[rt].cover = 1; if(l == r) return; int mid = (l + r) >> 1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update(int rt,int l,int r,int val) { if(l <= tree[rt].l && tree[rt].r <= r) { tree[rt].status = 1 << (val - 1); tree[rt].cover = 1; return; } if(tree[rt].cover) { tree[rt<<1].cover = tree[rt<<1|1].cover = tree[rt].cover; tree[rt<<1].status = tree[rt<<1|1].status = tree[rt].status; tree[rt].cover = 0; } int mid = (tree[rt].l + tree[rt].r) >> 1; if(mid >= l) update(rt<<1,l,r,val); if (mid < r) update(rt<<1|1,l,r,val);//右區間是從mid+1開始的,所以不取等 tree[rt].status = tree[rt<<1].status | tree[rt<<1|1].status; if(tree[rt<<1].cover && tree[rt<<1|1].cover && tree[rt<<1].status == tree[rt<<1|1].status) tree[rt].cover = 1; } int query(int rt,int l,int r) { if(l <= tree[rt].l && tree[rt].r <= r) return tree[rt].status; if(tree[rt].cover) return tree[rt].status; int mid = (tree[rt].l + tree[rt].r) >> 1; int ans = 0; if(l <= mid) ans |= query(rt<<1,l,r); if(mid < r) ans |= query(rt<<1|1,l,r); return ans; } int main() { char ch; int a,b,c; while(scanf("%d%d%d",&n,&color,&m)!=EOF) { build(1,1,n); while(m--) { getchar(); scanf("%c",&ch); if(ch == 'C') { scanf("%d%d%d",&a,&b,&c); if(a > b) swap(a,b); update(1,a,b,c); } else { scanf("%d%d",&a,&b); if(a > b) swap(a,b); int ans = query(1,a,b),sum = 0; for(int i = 0; i < color; i++) if(ans & (1 << i)) sum++; printf("%d\n",sum); } } } return 0; }