HDU 5023

来源:互联网 发布:色调 转化为rgb c语言 编辑:程序博客网 时间:2024/05/24 06:33

题意:和POJ 2777类似,建n的线段树,然后m个操作,P a b c 表示将ab区间的颜色换成c,Q a b表示查询ab的颜色,输出区间的颜色,按照从小到大的顺序,POJ 2777是输出区间颜色的个数。

思路:用位运算进行加速,lazy【id】表示的是我当前的第id位变成1之后转化成10进制的数。 比如大小为3的树,我给id=3的位置涂颜色3,那么我就将二进制从后往前数第3位变成1,就相当于二进制的100,那么lazy[id]=4;这题有坑,初始化的颜色都是2,我勒个去,一开始题目都没看利索,还以为初始化为1.

#include <stdio.h>#define maxn 1111111int sum[maxn<<2],ans[maxn<<2];int lazy[maxn<<2];void pushup(int id){sum[id]=sum[id<<1]|sum[id<<1|1];}void pushdown(int id){if(lazy[id]){lazy[id<<1]=lazy[id<<1|1]=lazy[id];sum[id<<1]=sum[id<<1|1]=lazy[id];lazy[id]=0;}}void build(int l,int r,int id){sum[id]=2;lazy[id]=0;if(l==r)return ;int mid=l+r>>1;build(l,mid,id<<1);build(mid+1,r,id<<1|1);pushup(id);}void updata(int L,int R,int c,int l,int r,int id){if(L<=l&&R>=r){sum[id]=c;lazy[id]=c;return ;}pushdown(id);int mid=l+r>>1;if(L<=mid)updata(L,R,c,l,mid,id<<1);if(R>mid)updata(L,R,c,mid+1,r,id<<1|1);pushup(id);}int query(int L,int R,int l,int r,int id){if(L<=l&&r<=R)return sum[id];pushdown(id);int mid=l+r>>1;int ans=0;if(L<=mid)ans|=query(L,R,l,mid,id<<1);if(R>mid)ans|=query(L,R,mid+1,r,id<<1|1);return ans;}int main(){int m,n,a,b,c,k;char op;while(scanf("%d %d",&n,&m),n||m){build(1,n,1);while(m--){getchar();scanf("%c",&op);if(op=='P'){scanf("%d %d %d",&a,&b,&c);updata(a,b,1<<(c-1),1,n,1);}else {scanf("%d %d",&a,&b);k=0;int res=query(a,b,1,n,1);for(int i=0;i<30;i++){if((res>>i)&1)ans[k++]=i+1;}for(int i=0;i<k;i++){if(i==0)printf("%d",ans[i]);else printf(" %d",ans[i]);}printf("\n");}}}return 0;}

0 0