博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1858 序列操作 (线段树)
阅读量:7081 次
发布时间:2019-06-28

本文共 3697 字,大约阅读时间需要 12 分钟。

题目链接:

题意:给一个01序列,有5种操作:

(1)0 L R 将[L,R]之间的数字都变成0;

(2)1 L R 将[L,R]之间的数字都变成1;

(3)2 L R 将[L R]之间的数字都取反;

(4)3 L R 询问[L R]之间1的个数;

(5)4 L R 询问[L,R]之间连续1的个数最大是多少

思路:

(1)每个节点信息:

l0,l1:左端开始连续01的个数;

r0,r1:右端开始连续01的个数;

max0,max1:区间内最长连续01的长度;

cnt0,cnt1:区间内01的个数

flag:-1表示无标记,0表示全为0,1表示全为1,2表示取反

(2)不管查询还是更新,最主要的是当前区间的flag不是-1时,向下传递该状态。

 

struct node{    int l0,l1,r0,r1,max0,max1,flag,len,cnt0,cnt1;    int L,R,mid;};const int MAX=100005;node a[MAX<<2];int n,m,p[MAX];void update(int t){    a[t].l0=a[t*2].l0;    if(a[t*2].l0==a[t*2].len) a[t].l0+=a[t*2+1].l0;    a[t].r0=a[t*2+1].r0;    if(a[t*2+1].r0==a[t*2+1].len) a[t].r0+=a[t*2].r0;    a[t].max0=max(a[t*2].max0,a[t*2+1].max0);    a[t].max0=max(a[t].max0,a[t*2].r0+a[t*2+1].l0);    a[t].cnt0=a[t*2].cnt0+a[t*2+1].cnt0;    a[t].l1=a[t*2].l1;    if(a[t*2].l1==a[t*2].len) a[t].l1+=a[t*2+1].l1;    a[t].r1=a[t*2+1].r1;    if(a[t*2+1].r1==a[t*2+1].len) a[t].r1+=a[t*2].r1;    a[t].max1=max(a[t*2].max1,a[t*2+1].max1);    a[t].max1=max(a[t].max1,a[t*2].r1+a[t*2+1].l1);    a[t].cnt1=a[t*2].cnt1+a[t*2+1].cnt1;}void build(int t,int L,int R){    a[t].L=L;    a[t].R=R;    a[t].mid=(L+R)>>1;    a[t].len=R-L+1;    a[t].flag=-1;    if(L==R)    {        a[t].l0=a[t].r0=a[t].max0=a[t].cnt0=!p[L];        a[t].l1=a[t].r1=a[t].max1=a[t].cnt1=p[L];        return;    }    build(t*2,L,a[t].mid);    build(t*2+1,a[t].mid+1,R);    update(t);}void swap(int &x,int &y){    int temp;    temp=x;    x=y;    y=temp;}void change(int t,int L,int R,int cmd){    if(a[t].L==L&&a[t].R==R)    {        if(cmd==0)        {            a[t].l0=a[t].r0=a[t].max0=a[t].cnt0=a[t].len;            a[t].l1=a[t].r1=a[t].max1=a[t].cnt1=0;            a[t].flag=0;        }        else if(cmd==1)        {            a[t].l0=a[t].r0=a[t].max0=a[t].cnt0=0;            a[t].l1=a[t].r1=a[t].max1=a[t].cnt1=a[t].len;            a[t].flag=1;        }        else if(cmd==2)        {            swap(a[t].l0,a[t].l1);            swap(a[t].r0,a[t].r1);            swap(a[t].cnt0,a[t].cnt1);            swap(a[t].max0,a[t].max1);            a[t].flag=1-a[t].flag;        }        return;    }    if(a[t].flag>=0)    {        change(t*2,a[t*2].L,a[t*2].R,a[t].flag);        change(t*2+1,a[t*2+1].L,a[t*2+1].R,a[t].flag);        a[t].flag=-1;    }    if(R<=a[t].mid) change(t*2,L,R,cmd);    else if(L>a[t].mid) change(t*2+1,L,R,cmd);    else    {        change(t*2,L,a[t].mid,cmd);        change(t*2+1,a[t].mid+1,R,cmd);    }    update(t);}node get(int t,int L,int R){    if(a[t].L==L&&a[t].R==R) return a[t];    if(a[t].flag>=0)    {        change(t*2,a[t*2].L,a[t*2].R,a[t].flag);        change(t*2+1,a[t*2+1].L,a[t*2+1].R,a[t].flag);        a[t].flag=-1;    }    node t1,t2,t3;    if(R<=a[t].mid) return get(t*2,L,R);    else if(L>a[t].mid) return get(t*2+1,L,R);    else    {        t1=get(t*2,L,a[t].mid);        t2=get(t*2+1,a[t].mid+1,R);        t3.cnt1=t1.cnt1+t2.cnt1;        t3.l1=t1.l1;        if(t1.l1==t1.len) t3.l1+=t2.l1;        t3.r1=t2.r1;        if(t2.r1==t2.len) t3.r1+=t1.r1;        t3.max1=max(t1.max1,t2.max1);        t3.max1=max(t3.max1,t1.r1+t2.l1);        t3.len=t1.len+t2.len;        return t3;    }}int main(){    while(scanf("%d%d",&n,&m)!=-1)    {        int i;        for(i=1;i<=n;i++) scanf("%d",p+i);        build(1,1,n);        int cmd,L,R;        node t;        for(i=1;i<=m;i++)        {            scanf("%d%d%d",&cmd,&L,&R);            L++;            R++;            if(cmd<=2) change(1,L,R,cmd);            else            {                t=get(1,L,R);                if(cmd==3) printf("%d\n",t.cnt1);                else printf("%d\n",t.max1);            }        }    }    return 0;}

  

                     

转载于:https://www.cnblogs.com/jianglangcaijin/archive/2012/12/04/2802011.html

你可能感兴趣的文章
从蚂蚁金服实践入手,带你深入了解 Service Mesh
查看>>
通过DevOps考古学了解生产环境
查看>>
nginx lua指令执行顺序
查看>>
新书问答:Agile Management
查看>>
精益企业中架构师的角色
查看>>
angular-cli创建angular2项目并添加ng2-bootstrap
查看>>
leetcode讲解之开篇--刷题技巧
查看>>
Ruby 2.5.0概览
查看>>
改变从内部开始:开发者与管理者的协作
查看>>
mac使用minikube安装kubernetes
查看>>
Chrome开发者工具中关于“Deferred long-running timer task(s) ”的警告
查看>>
聊聊跨域
查看>>
Windows 下使用 MinGW 编译安装 (G)vim 添加 Lua 等编程语言支持
查看>>
Objective-C基本数据类型
查看>>
利用localStorage本地储存js文件
查看>>
[聊一聊系列]聊一聊百度移动端首页前端速度那些事儿
查看>>
shell script编程小结——附带实例
查看>>
在 Laravel 项目中使用 Glup 之 Laravel-Elixir
查看>>
Nginx、CGI、FastCGI、PHP-CGI、PHP-FPM处理流程
查看>>
Tornado 4.3文档翻译: web框架-RequestHandler和Application 类
查看>>