zoukankan      html  css  js  c++  java
  • 【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 }


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

  • 相关阅读:
    hdu5360 Hiking(水题)
    hdu5348 MZL's endless loop(欧拉回路)
    hdu5351 MZL's Border(规律题,java)
    hdu5347 MZL's chemistry(打表)
    hdu5344 MZL's xor(水题)
    hdu5338 ZZX and Permutations(贪心、线段树)
    hdu 5325 Crazy Bobo (树形dp)
    hdu5323 Solve this interesting problem(爆搜)
    hdu5322 Hope(dp)
    Lightoj1009 Back to Underworld(带权并查集)
  • 原文地址:https://www.cnblogs.com/Judge/p/9894026.html
Copyright © 2011-2022 走看看