poj-2777 线段树lazy标记+位运算

来源:互联网 发布:童装淘宝店铺简介 编辑:程序博客网 时间:2024/05/22 02:56

题目来源:http://poj.org/problem?id=2777

题目意思很好懂  就是求解一段区间不同的数字的个数

由于数字的种类小于30

所以可以用位运算来代表不同的种类  纠结了好久开始一直TLE后来才改的位运算

然后用到的就是区间的覆盖问题了

值得注意的就是开始的颜色为 1   A可能大于B

#include <iostream>#include <cstdio>#include <cstring>#define MAX 100010using namespace std;typedef struct{    int l;    int r;    int cov;    int cc;} Tree;Tree tree[MAX*5];int L,T,O;void update(int i){    if(tree[i].cov!=-1)    {        tree[i].cc=tree[i].cov; //直接覆盖        tree[i<<1].cov=tree[i].cov;        tree[(i<<1)+1].cov=tree[i].cov;        tree[i].cov=-1;    }}int build(int i,int l,int r){    int mid;    tree[i].l=l;    tree[i].r=r;    tree[i].cov=-1;    tree[i].cc=1;    if(l==r)        return 0;    mid=(l+r)>>1;    build(i<<1,l,mid);    build((i<<1)+1,mid+1,r);}int cover(int i,int x,int y,int now){    int mid;    update(i);    if((x<=tree[i].l)&&(y>=tree[i].r))    {        tree[i].cov=now;        return 0;    }    mid=(tree[i].l+tree[i].r)>>1;    if(x<=mid)   cover(i<<1,x,y,now);    if(y>mid)    cover((i<<1)+1,x,y,now);    update(i<<1);    update((i<<1)+1);    tree[i].cc=(tree[i<<1].cc|tree[(i<<1)+1].cc);}int cal(int i,int x,int y){    int mid;    int ans=0;    update(i);    if ((x<=tree[i].l)&&(y>=tree[i].r))        return tree[i].cc;    mid=(tree[i].l+tree[i].r)>>1;    if (x<=mid)  ans=(ans|cal(i<<1,x,y));  //位运算 或    if (y>mid)   ans=(ans|cal((i<<1)+1,x,y));    update(i<<1);    update((i<<1)+1);    tree[i].cc=(tree[i<<1].cc | tree[(i<<1)+1].cc); // 位运算 或    return ans;}int MUN(int i){    int count = 0;    while(i)    {        if(i & 1) count ++;        i = i >> 1;    }    return count;}int main(){    scanf("%d%d%d",&L,&T,&O);    build(1,1,L);    char ch;    for(int i=1; i<=O; i++)    {        getchar();        ch=getchar();        if(ch=='C')        {            int x,y,c;            scanf("%d%d%d",&x,&y,&c);            if(x>y)            {                x^=y^=x^=y;            }            int v=(1<<(c-1));  //位运算 第几种颜色就是把1 左移几位            cover(1,x,y,v);        }        else        {            int x,y;            scanf("%d%d",&x,&y);            if(x>y)            {                x^=y^=x^=y;            }            int ans=cal(1,x,y);            printf("%d\n",MUN(ans));        }    }}


原创粉丝点击