【poj2777】【线段树】Count Color

来源:互联网 发布:video.js怎么播放flv 编辑:程序博客网 时间:2024/04/30 14:45

非常水的线段树了吧,注意到最多只有30种颜色,所以我们可以对线段树的每一个节点用一个数来表示这个节点有哪些颜色最后直接用位运算统计

需要注意的地方:

1、一开始所有的颜色都为1

2、有可能出现a > b的情况

代码:

#include<cstdio>#include<cstring>#define lson l,m,rt << 1#define rson m + 1,r,rt << 1 | 1using namespace std;const int maxn = 100000 + 10;int color[maxn<<2],lazy[maxn<<2];int n,m,t;void init(){freopen("poj2777.in","r",stdin);freopen("poj2777.out","w",stdout);}void swap(int &a,int &b){int t = a;a = b;b = t;}void push_up(int rt){color[rt] = color[rt<<1] | color[rt<<1|1];}void push_down(int rt){if(lazy[rt]){lazy[rt<<1] = true;lazy[rt<<1|1] = true;color[rt<<1] = color[rt];color[rt<<1|1] = color[rt];lazy[rt] = 0;}}int lowbit(int x){return x & -x;}void build(int l,int r,int rt){if(l == r){color[rt] |= 1;return;}int m = (l + r) >> 1;build(lson);build(rson);push_up(rt);}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){color[rt] = (1 << (c - 1));lazy[rt] = true;return;}push_down(rt);int m = (l + r) >> 1;if(L <= m)update(L,R,c,lson);if(R > m)update(L,R,c,rson);push_up(rt);}int query(int L,int R,int l,int r,int rt){if(L <= l && r <= R)return color[rt];push_down(rt);int m = (l + r) >> 1;int lc = 0,rc = 0;if(L <= m)lc = query(L,R,lson);if(R > m)rc = query(L,R,rson);int ret = lc | rc;return ret;}void readdata(){scanf("%d%d%d",&n,&t,&m);build(1,n,1);for(int i = 1;i <= m;i++){char op[10];scanf("%s",op);if(op[0] == 'C'){int l,r,col;if(l > r)swap(l,r);scanf("%d%d%d",&l,&r,&col);update(l,r,col,1,n,1);}if(op[0] == 'P'){int l,r;scanf("%d%d",&l,&r);if(l > r)swap(l,r);int tmp = query(l,r,1,n,1);int cnt = 0;for(int i = 0;i < t;i++)if(tmp & (1 << i))cnt++;printf("%d\n",cnt);}}}int main(){init();readdata();return 0;}


原创粉丝点击