• 【SCOI2010】序列操作


    各种繁琐的线段树标记操作。。。赤裸裸的码农题。

    调了一个晚上,最后写篇题解。

    题解亮点:代码短,~~跑得慢(连第一页都没挤进去)~~


    其实我跟你们说啊,代码短是好事~~(这里不是说压行好,我的代码不压行也没那么长)~~,因为代码短好调啊,几个类似的语句写个函数,既满足了懒人需要(减少码量),而且也让代码思路清晰,没有那么杂乱了。


    the code:

     1 //by Judge
     2 #include<cstdio>
     3 #include<iostream>
     4 using namespace std;
     5 const int M=2e5+5;
     6 #ifndef Judge
     7 #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     8 #endif
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline int read(){ int x=0,f=1; char c=getchar();
    11     for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    12     for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
    13 } char sr[1<<21],z[20];int C=-1,Z;
    14 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    15 inline void print(int x,char chr='
    '){
    16     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    17     while(z[++Z]=x%10+48,x/=10);
    18     while(sr[++C]=z[Z],--Z);sr[++C]=chr;
    19 } inline void cmax(int& a,int b){ if(a<b) a=b; }
    20 struct node{ int l,r,len,tag,rev;
    21     int sum,max[2],lmax[2],rmax[2];
    22 }t[M<<2],zero; int n,m,v[M];
    23 #define ls k<<1
    24 #define rs k<<1|1
    25 inline node merge(node a,node b){ //懒人合并
    26     static node c;
    27     c.sum=a.sum+b.sum;
    28     for(int i=0;i<=1;++i){
    29         c.lmax[i]=a.lmax[i];
    30         if(a.lmax[i]==a.len)
    31             c.lmax[i]+=b.lmax[i];
    32         c.rmax[i]=b.rmax[i];
    33         if(b.rmax[i]==b.len)
    34             c.rmax[i]+=a.rmax[i];
    35         c.max[i]=a.rmax[i]+b.lmax[i];
    36         cmax(c.max[i],a.max[i]);
    37         cmax(c.max[i],b.max[i]);
    38     } return c;
    39 } inline void pushup(int k){ //懒人pushup
    40     t[0]=merge(t[ls],t[rs]);
    41     t[k].sum=t[0].sum;
    42     for(int i=0;i<=1;++i){
    43         t[k].max[i]=t[0].max[i];
    44         t[k].lmax[i]=t[0].lmax[i];
    45         t[k].rmax[i]=t[0].rmax[i];
    46     }
    47 } inline void chg(int k,int v){ //懒人change
    48     if(v<2){
    49         t[k].sum=t[k].len*v,t[k].tag=v,t[k].rev=0;
    50         t[k].max[v]=t[k].lmax[v]=t[k].rmax[v]=t[k].len;
    51         t[k].max[v^1]=t[k].lmax[v^1]=t[k].rmax[v^1]=0;
    52     } else if(v==2){
    53         t[k].sum=t[k].len-t[k].sum;
    54         if(t[k].tag!=-1) t[k].tag^=1;
    55         else t[k].rev^=1;
    56         swap(t[k].max[0],t[k].max[1]);
    57         swap(t[k].lmax[0],t[k].lmax[1]);
    58         swap(t[k].rmax[0],t[k].rmax[1]);
    59     }
    60 } inline void pushdown(int k){ //pushdown可以非常短
    61     if(t[k].tag!=-1)
    62         t[k].rev=0,chg(ls,t[k].tag),
    63         chg(rs,t[k].tag),t[k].tag=-1;
    64     else if(t[k].rev)
    65         chg(ls,2),chg(rs,2),t[k].rev=0;
    66 } void build(int k,int l,int r){ /*     然后都是线段树常规操作   */
    67     t[k].l=l,t[k].r=r,t[k].len=r-l+1,t[k].tag=-1;
    68     if(l==r){ int c=v[l]; t[k].sum=c;
    69         t[k].max[c]=t[k].lmax[c]=t[k].rmax[c]=1; return ;
    70     } int mid=l+r>>1; build(ls,l,mid),build(rs,mid+1,r),pushup(k);
    71 } void update(int k,int L,int R,int opt){
    72     if(L<=t[k].l&&t[k].r<=R) return chg(k,opt);
    73     int mid=t[k].l+t[k].r>>1; pushdown(k);
    74     if(L<=mid) update(ls,L,R,opt);
    75     if(R>mid) update(rs,L,R,opt); pushup(k);
    76 } int query(int k,int L,int R){
    77     if(L>t[k].r||t[k].l>R) return 0;
    78     if(L<=t[k].l&&t[k].r<=R) return t[k].sum;
    79     pushdown(k); int mid=t[k].l+t[k].r>>1;
    80     return query(ls,L,R)+query(rs,L,R);
    81 } node query_mx(int k,int L,int R){
    82     if(L>t[k].r||t[k].l>R) return zero; //zero作用和他的名字一样,merge的时候就不算贡献了
    83     if(L<=t[k].l&&t[k].r<=R) return t[k]; pushdown(k);
    84     return merge(query_mx(ls,L,R),query_mx(rs,L,R));
    85 } int main(){ n=read(),m=read();
    86     for(int i=1;i<=n;++i) v[i]=read();
    87     build(1,1,n);
    88     for(int opt,l,r;m;--m){ //处理各种操作
    89         opt=read(),l=read()+1,r=read()+1;
    90         if(opt<3) update(1,l,r,opt);
    91         else if(opt==3) print(query(1,l,r));
    92         else if(opt==4) print(query_mx(1,l,r).max[1]);
    93     } return Ot(),0;
    94 }


    不压行也就一百一二十行吧。

  • 相关阅读:
    Linux 系统挂载数据盘
    Apache Rewrite规则笔记
    linux fdisk分区笔记
    阿里云linux配置
    linux 下安装mysql相关笔记
    ShopNC目录结构分析
    今天开始出发做ShopNC
    svn相关笔记
    linux学习笔记-不定时更新
    Oracle EBS Java Applet报错:找不到类
  • 原文地址:https://www.cnblogs.com/Judge/p/9894026.html
Copyright © 2020-2023  润新知