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

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

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

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


the code:

 //by Judge
#include<cstdio>
#include<iostream>
using namespace std;
const int M=2e5+;
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[<<],*p1=buf,*p2=buf;
inline int read(){ int x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-''; return x*f;
} char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x,char chr='\n'){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]=chr;
} inline void cmax(int& a,int b){ if(a<b) a=b; }
struct node{ int l,r,len,tag,rev;
int sum,max[],lmax[],rmax[];
}t[M<<],zero; int n,m,v[M];
#define ls k<<1
#define rs k<<1|1
inline node merge(node a,node b){ //懒人合并
static node c;
c.sum=a.sum+b.sum;
for(int i=;i<=;++i){
c.lmax[i]=a.lmax[i];
if(a.lmax[i]==a.len)
c.lmax[i]+=b.lmax[i];
c.rmax[i]=b.rmax[i];
if(b.rmax[i]==b.len)
c.rmax[i]+=a.rmax[i];
c.max[i]=a.rmax[i]+b.lmax[i];
cmax(c.max[i],a.max[i]);
cmax(c.max[i],b.max[i]);
} return c;
} inline void pushup(int k){ //懒人pushup
t[]=merge(t[ls],t[rs]);
t[k].sum=t[].sum;
for(int i=;i<=;++i){
t[k].max[i]=t[].max[i];
t[k].lmax[i]=t[].lmax[i];
t[k].rmax[i]=t[].rmax[i];
}
} inline void chg(int k,int v){ //懒人change
if(v<){
t[k].sum=t[k].len*v,t[k].tag=v,t[k].rev=;
t[k].max[v]=t[k].lmax[v]=t[k].rmax[v]=t[k].len;
t[k].max[v^]=t[k].lmax[v^]=t[k].rmax[v^]=;
} else if(v==){
t[k].sum=t[k].len-t[k].sum;
if(t[k].tag!=-) t[k].tag^=;
else t[k].rev^=;
swap(t[k].max[],t[k].max[]);
swap(t[k].lmax[],t[k].lmax[]);
swap(t[k].rmax[],t[k].rmax[]);
}
} inline void pushdown(int k){ //pushdown可以非常短
if(t[k].tag!=-)
t[k].rev=,chg(ls,t[k].tag),
chg(rs,t[k].tag),t[k].tag=-;
else if(t[k].rev)
chg(ls,),chg(rs,),t[k].rev=;
} void build(int k,int l,int r){ /* 然后都是线段树常规操作 */
t[k].l=l,t[k].r=r,t[k].len=r-l+,t[k].tag=-;
if(l==r){ int c=v[l]; t[k].sum=c;
t[k].max[c]=t[k].lmax[c]=t[k].rmax[c]=; return ;
} int mid=l+r>>; build(ls,l,mid),build(rs,mid+,r),pushup(k);
} void update(int k,int L,int R,int opt){
if(L<=t[k].l&&t[k].r<=R) return chg(k,opt);
int mid=t[k].l+t[k].r>>; pushdown(k);
if(L<=mid) update(ls,L,R,opt);
if(R>mid) update(rs,L,R,opt); pushup(k);
} int query(int k,int L,int R){
if(L>t[k].r||t[k].l>R) return ;
if(L<=t[k].l&&t[k].r<=R) return t[k].sum;
pushdown(k); int mid=t[k].l+t[k].r>>;
return query(ls,L,R)+query(rs,L,R);
} node query_mx(int k,int L,int R){
if(L>t[k].r||t[k].l>R) return zero; //zero作用和他的名字一样,merge的时候就不算贡献了
if(L<=t[k].l&&t[k].r<=R) return t[k]; pushdown(k);
return merge(query_mx(ls,L,R),query_mx(rs,L,R));
} int main(){ n=read(),m=read();
for(int i=;i<=n;++i) v[i]=read();
build(,,n);
for(int opt,l,r;m;--m){ //处理各种操作
opt=read(),l=read()+,r=read()+;
if(opt<) update(,l,r,opt);
else if(opt==) print(query(,l,r));
else if(opt==) print(query_mx(,l,r).max[]);
} return Ot(),;
}

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

【SCOI2010】序列操作的更多相关文章

  1. bzoj 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...

  2. BZOJ 1858: [Scoi2010]序列操作( 线段树 )

    略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...

  3. bzoj1858[Scoi2010]序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 3079  Solved: 1475[Submit][Statu ...

  4. BZOJ_1858_[Scoi2010]序列操作_线段树

    BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...

  5. 【题解】Luogu P2572 [SCOI2010]序列操作

    原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...

  6. P2572 [SCOI2010]序列操作

    对自己 & \(RNG\) : 骄兵必败 \(lpl\)加油! P2572 [SCOI2010]序列操作 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要 ...

  7. BZOJ1858 [Scoi2010]序列操作(线段树)

    题目链接 [Scoi2010]序列操作 考验代码能力的一道好题. 思想还是很简单的(直接上线段树),但是比较难写. #include <bits/stdc++.h> using names ...

  8. (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作

    二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...

  9. 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 3397 Solved: 1624 [Submit][Statu ...

  10. SCOI2010 序列操作

    2421 序列操作 http://codevs.cn/problem/2421/ 2010年省队选拔赛四川   题目描述 Description lxhgww最近收到了一个01序列,序列里面包含了n个 ...

随机推荐

  1. Tips and Tricks for Debugging in chrome

    Tips and Tricks for Debugging in chrome Pretty print On sources panel ,clicking on the {} on the bot ...

  2. 【坑】zsh和oh-my-zsh卸载后导致无法登陆

    apt-get remove zsh 然后断开终端,就再也连不上了,崩溃啊! 以下登陆为www用户登陆 各种找,到这里 https://www.cnblogs.com/EasonJim/p/78630 ...

  3. 理解BFC

    BFC:块格式化上下文(Block Formatting Context) 是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域. BFC 是一 ...

  4. Python数据挖掘和机器学习

    -----------------------------2017.8.9--------------------------------- 先占个坑 在接下来的一个半月里(即从现在到十一) 我将结合 ...

  5. 二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程

    23.1 进程链和进程扇 23.1.1 概念 进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程.... 这种就为进程链 进程扇:一个父进程构建出多个子进程,子进程都 ...

  6. jdbc 日期处理问题

    1.从结果集中取得日期部分 resultSet.getDate();  --2013-01-07 2.从结果集中取得时间部分 resultSet.getTime()   --22:08:09 3.从结 ...

  7. Linux之文件恢复[extundelete,针对rm]

    [恢复过程] 1.下载+安装extundelete cd /tmp wget wget http://jaist.dl.sourceforge.net/project/extundelete/extu ...

  8. python 之模块random

    随机形成字母和数字组成的五位字符码. [root@localhost python]# vim timee.py import random def coder(): code = '' for i ...

  9. Kotlin中构造方法的参数var val 和 什么都没有的区别

    1.什么都没有,在该类中使不能使用的, 这个参数的作用就是,传递给父类的构造方法 2.使用var 可以在类中使用,相当于 我们声明了一个该类中定义了一个private 的成员变量 3.val表示不让修 ...

  10. exsi5.5以上版本支持虚拟机的二次虚拟化

    从存储里找到虚拟机的位置 下载并修改虚拟机的.vmx配置文件(记得做好备份) 打开<虚拟机名>.vmx文件,在末尾追加如下字段,保存退出. nce.enable = TRUE hyperv ...