• 解题:SCOI 2010 序列操作


    题面

    线段树......模板题(雾?

    然而两种标记会互相影响,必须保证每次只放一个(不然就不知道怎么放了),具体的影响就是:

    翻转标记会使得覆盖标记一起翻转,下放的时候就是各种swap

    覆盖标记会抹掉翻转标记,下放的时候好像挺正常的

    然后就是码码码+细节

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int N=100005;
      6 struct a{int ll,rr,vv;};
      7 int val[4*N],last[4*N][2],lst[4*N][2],rst[4*N][2];
      8 int num[N],laz1[4*N],laz2[4*N];
      9 int n,m,t1,t2,t3;
     10 void pushup(int nde,int l,int r)
     11 {
     12     int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
     13     val[nde]=val[ls]+val[rs];
     14     //value
     15     lst[nde][1]=(last[ls][1]==mid-l+1)?last[ls][1]+lst[rs][1]:lst[ls][1];
     16     rst[nde][1]=(last[rs][1]==r-mid)?last[rs][1]+rst[ls][1]:rst[rs][1];
     17     last[nde][1]=max(rst[ls][1]+lst[rs][1],max(last[ls][1],last[rs][1]));
     18     //longest continuing one
     19     lst[nde][0]=(last[ls][0]==mid-l+1)?last[ls][0]+lst[rs][0]:lst[ls][0];
     20     rst[nde][0]=(last[rs][0]==r-mid)?last[rs][0]+rst[ls][0]:rst[rs][0];
     21     last[nde][0]=max(rst[ls][0]+lst[rs][0],max(last[ls][0],last[rs][0]));
     22     //longest continuing zero
     23 }
     24 void create(int nde,int l,int r)
     25 {
     26     if(l==r)
     27     {
     28         last[nde][0]=lst[nde][0]=rst[nde][0]=(num[l]^1);
     29         val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=num[l];
     30     }
     31     else
     32     {
     33         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
     34         create(ls,l,mid),create(rs,mid+1,r);
     35         pushup(nde,l,r);
     36     }
     37 }
     38 void release(int nde,int l,int r)
     39 {
     40     int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
     41     if(laz2[nde])
     42     {
     43         if(~laz1[ls]) laz1[ls]^=1; else laz2[ls]^=1;
     44         if(~laz1[rs]) laz1[rs]^=1; else laz2[rs]^=1;
     45         val[ls]=(mid-l+1)-val[ls],val[rs]=(r-mid)-val[rs];
     46         //reversing
     47         swap(last[ls][0],last[ls][1]),swap(last[rs][0],last[rs][1]);
     48         swap(lst[ls][0],lst[ls][1]),swap(lst[rs][0],lst[rs][1]);
     49         swap(rst[ls][0],rst[ls][1]),swap(rst[rs][0],rst[rs][1]);
     50         //a lot of swaps......
     51         laz2[nde]=0;
     52         //refresh
     53     }
     54     //release the lazy tag of intervals reversing
     55     else if(~laz1[nde])
     56     {
     57         laz1[ls]=laz1[nde],laz1[rs]=laz1[nde],laz2[ls]=0,laz2[rs]=0;
     58         //to the left/right son
     59         val[ls]=last[ls][1]=lst[ls][1]=rst[ls][1]=(mid-l+1)*laz1[nde];
     60         val[rs]=last[rs][1]=lst[rs][1]=rst[rs][1]=(r-mid)*laz1[nde]; 
     61         //longest continuing one
     62         last[ls][0]=lst[ls][0]=rst[ls][0]=(mid-l+1)*(laz1[nde]^1);
     63         last[rs][0]=lst[rs][0]=rst[rs][0]=(r-mid)*(laz1[nde]^1); 
     64         //longest continuing zero
     65         laz1[nde]=-1;
     66         //refresh
     67     }
     68     //release the lazy tag of intervals covering
     69 }
     70 void Change(int nde,int l,int r,int nl,int nr,int task)
     71 {
     72     if(l>nr||r<nl)
     73         return ;
     74     else if(l>=nl&&r<=nr)
     75     {
     76         last[nde][0]=lst[nde][0]=rst[nde][0]=(task^1)*(r-l+1);
     77         val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=task*(r-l+1);
     78         laz1[nde]=task,laz2[nde]=0;
     79     }
     80     else
     81     {
     82         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
     83         Change(ls,l,mid,nl,nr,task),Change(rs,mid+1,r,nl,nr,task);
     84         pushup(nde,l,r); 
     85     }
     86 }
     87 void Reverse(int nde,int l,int r,int nl,int nr)
     88 {
     89     if(l>nr||r<nl)
     90         return ;
     91     else if(l>=nl&&r<=nr)
     92     {
     93         val[nde]=(r-l+1)-val[nde],swap(last[nde][0],last[nde][1]);
     94         swap(lst[nde][0],lst[nde][1]),swap(rst[nde][0],rst[nde][1]);
     95         if(~laz1[nde]) laz1[nde]^=1; else laz2[nde]^=1;
     96     }
     97     else
     98     {
     99         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
    100         Reverse(ls,l,mid,nl,nr),Reverse(rs,mid+1,r,nl,nr); pushup(nde,l,r); 
    101     }
    102 }
    103 int Vquery(int nde,int l,int r,int nl,int nr)
    104 {
    105     if(l>nr||r<nl)
    106         return 0;
    107     else if(l>=nl&&r<=nr)
    108         return val[nde];
    109     else
    110     {
    111         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
    112         return Vquery(ls,l,mid,nl,nr)+Vquery(rs,mid+1,r,nl,nr);
    113     }
    114 }
    115 a Lquery(int nde,int l,int r,int nl,int nr)
    116 {
    117     if(l>=nl&&r<=nr)
    118         return (a){lst[nde][1],rst[nde][1],last[nde][1]};
    119     else
    120     {
    121         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
    122         if(nr<=mid) return Lquery(ls,l,mid,nl,nr);
    123         if(nl>mid) return Lquery(rs,mid+1,r,nl,nr); 
    124         a Q1=Lquery(ls,l,mid,nl,nr),Q2=Lquery(rs,mid+1,r,nl,nr),ret;
    125         ret.vv=max(max(Q1.vv,Q2.vv),Q1.rr+Q2.ll);
    126         ret.ll=(Q1.vv==(mid-l+1))?Q1.vv+Q2.ll:Q1.ll;
    127         ret.rr=(Q2.vv==(r-mid))?Q2.vv+Q1.rr:Q2.rr;
    128         return ret;
    129     }
    130 }
    131 int main ()
    132 {
    133     scanf("%d%d",&n,&m);
    134     for(int i=1;i<=n;i++)
    135         scanf("%d",&num[i]);
    136     create(1,1,n);
    137     memset(laz1,-1,sizeof laz1);
    138     for(int i=1;i<=m;i++)
    139     {
    140         scanf("%d%d%d",&t1,&t2,&t3),t2++,t3++;
    141         if(!t1) Change(1,1,n,t2,t3,0);
    142         else if(t1==1) Change(1,1,n,t2,t3,1);
    143         else if(t1==2) Reverse(1,1,n,t2,t3);
    144         else if(t1==3) printf("%d
    ",Vquery(1,1,n,t2,t3));
    145         else printf("%d
    ",Lquery(1,1,n,t2,t3).vv);
    146     }
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    HBase目录
    HBase介绍及简易安装(转)
    Hadoop目录
    通过java读取HDFS的数据 (转)
    Flume-NG一些注意事项(转)
    spark读取 kafka nginx网站日志消息 并写入HDFS中(转)
    Java开发牛人十大必备网站
    HTTP协议状态码详解(HTTP Status Code)(转)
    Flume NG 配置详解(转)
    Android笔记(五)利用Intent启动活动
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9729664.html
Copyright © 2020-2023  润新知