HDU 5023 线段树+状压

来源:互联网 发布:小学生编程比赛 编辑:程序博客网 时间:2024/06/09 17:24

2014 ACM/ICPC Asia Regional Guangzhou Online

N个节点,M个操作。

P操作把l-r全部改为x (1<=x<=30)

Q操作询问l-r出现的数字,升序输出


线段树成端更新+成端查找

因为X最大30,用二进制压缩存储已经出现的数字。

#include "stdio.h"#include "string.h"struct node{    int l,r;    __int64 x,lazy;}data[4001000];__int64 ans;__int64 b[40];void Pushdown(int k){    if (data[k].l==data[k].r) return ;    if (data[k].lazy==0) return ;    data[k*2].lazy=data[k*2].x=data[k].lazy;    data[k*2+1].lazy=data[k*2+1].x=data[k].lazy;    data[k].lazy=0;}void build(int l,int r,int k){    int mid;    data[k].l=l;    data[k].r=r;    data[k].lazy=0;    data[k].x=2;    if (l==r) return ;    mid=(l+r)/2;    build(l,mid,k*2);    build(mid+1,r,k*2+1);}void updata(int l,int r,int k,int op){    int mid;    if (data[k].l==l && data[k].r==r)    {        data[k].lazy=b[op];        data[k].x=b[op];        return ;    }    Pushdown(k);    mid=(data[k].l+data[k].r)/2;    if (r<=mid) updata(l,r,k*2,op);    else        if (l>mid) updata(l,r,k*2+1,op);    else    {        updata(l,mid,k*2,op);        updata(mid+1,r,k*2+1,op);    }    if (data[k*2].x==data[k*2+1].x) data[k].x=data[k*2].x;    else data[k].x=-1;}void query(int l,int r,int k){    int mid;    if (data[k].x!=-1)    {        ans|=data[k].x;        return;    }    mid=(data[k].l+data[k].r)/2;    Pushdown(k);    if (r<=mid) query(l,r,k*2);    else        if (l>mid) query(l,r,k*2+1);    else    {        query(l,mid,k*2);        query(mid+1,r,k*2+1);    }}void pri(){    int first,i,x;    first=1;    for (i=1;i<=30;i++)    {        x=ans%2;        if (x==1)        {            if (first==0) printf(" ");            first=0;            printf("%d",i);        }        ans/=2;    }    printf("\n");}int main(){    int n,m,l,i,r,x;    char op;    b[1]=1;    for (i=2;i<=30;i++)        b[i]=b[i-1]*2;    while (scanf("%d%d",&n,&m)!=EOF)    {        if (n==0 && m==0) break;        build(1,n,1);        while (m--)        {            getchar();            scanf("%c%d%d",&op,&l,&r);            if (op=='P')            {                scanf("%d",&x);                updata(l,r,1,x);            }            else            {                ans=0;                query(l,r,1);                pri();            }        }    }    return 0;}




1 0
原创粉丝点击