zoukankan      html  css  js  c++  java
  • [bzoj1858]序列操作

    考虑建立一棵线段树,维护:1.左端点的连续1和;2.右端点的连续1和;3.最长1的连续子序列;4.1的个数;5.将0和1交换后上面的四项;6.懒标记
    具体实现中,需要注意细节,可以看代码(比较短)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define L (k<<1)
     5 #define R (L+1)
     6 #define mid (l+r>>1)
     7 struct ji{
     8     int sum,ls,rs,ans;
     9 }f0[N<<2],f1[N<<2];
    10 int n,m,p,x,y,laz[N<<2];
    11 ji merge(ji x,ji y){
    12     if (x.sum<0)return y;
    13     if (y.sum<0)return x; 
    14     ji z;
    15     z.sum=x.sum+y.sum;
    16     z.ls=x.ls+((x.ls==x.sum)&&(x.rs==x.sum)&&(x.sum))*y.ls;
    17     z.rs=y.rs+((y.rs==y.sum)&&(y.ls==y.sum)&&(y.sum))*x.rs;
    18     z.ans=max(max(x.ans,y.ans),x.rs+y.ls);
    19     return z;
    20 }
    21 int merge(int x,int y){
    22     if ((x<0)||(y<0))return x+y+1;
    23     if ((x==2)&&(y==2))return -1;
    24     if (x==2)return y^1;
    25     return x;
    26 }
    27 void upd(int k,int l,int r,int x){
    28     if (x<0)return;
    29     if (x<2){
    30         laz[k]=x;
    31         f0[k].sum=f0[k].ls=f0[k].rs=f0[k].ans=(x^1)*(r-l+1);
    32         f1[k].sum=f1[k].ls=f1[k].rs=f1[k].ans=x*(r-l+1);
    33         return;
    34     }
    35     swap(f0[k],f1[k]);
    36     if (laz[k]<0)laz[k]=2;
    37     else
    38         if (laz[k]>1)laz[k]=-1;
    39         else laz[k]^=1;
    40 }
    41 void up(int k,int l,int r){
    42     f0[k]=merge(f0[L],f0[R]);
    43     f1[k]=merge(f1[L],f1[R]);
    44     upd(k,l,r,-1);
    45 }
    46 void down(int k,int l,int r){
    47     if (laz[k]<0)return;
    48     upd(L,l,mid,laz[k]);
    49     upd(R,mid+1,r,laz[k]);
    50     laz[k]=-1;
    51 }
    52 void update(int k,int l,int r,int x,int y,int z){
    53     if ((l>y)||(x>r))return;
    54     if ((x<=l)&&(r<=y)){
    55         upd(k,l,r,z);
    56         return;
    57     }
    58     down(k,l,r);
    59     update(L,l,mid,x,y,z);
    60     update(R,mid+1,r,x,y,z);
    61     up(k,l,r);
    62 }
    63 ji query(int k,int l,int r,int x,int y){
    64     if ((l>y)||(x>r))return ji{-1,0,0,0};
    65     if ((x<=l)&&(r<=y))return f1[k];
    66     down(k,l,r);
    67     return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
    68 }
    69 int main(){
    70     scanf("%d%d",&n,&m);
    71     for(int i=1;i<=n;i++){
    72         scanf("%d",&x);
    73         update(1,1,n,i,i,x);
    74     }
    75     for(int i=1;i<=m;i++){
    76         scanf("%d%d%d",&p,&x,&y);
    77         x++,y++;
    78         if (p<3)update(1,1,n,x,y,p);
    79         else{
    80             ji o=query(1,1,n,x,y);
    81             if (p==3)printf("%d
    ",o.sum);
    82             if (p==4)printf("%d
    ",o.ans);
    83         }
    84     }
    85 }
    View Code
  • 相关阅读:
    头插法建立单链表
    顺序表
    栈的顺序存储实现
    折半查找
    myeclipe 快捷键盘
    ztree redio单选按钮
    webuploader上传进度条 上传删除
    svn乱码解决办法
    异构SOA系统架构之Asp.net实现(兼容dubbo)
    RPC框架
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11869401.html
Copyright © 2011-2022 走看看