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

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

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

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


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. WebStorm记录(3)

    连通接口 接口 我自己理解前后端传输数据都是通过ajax方式 一般使用get和post两种方式传输数据 GET 接口 接口描述 获取登录验证码图片及密钥 HTTP方法 POST URL /captch ...

  2. [leetcode-128] 最长连续序列

    给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, ...

  3. UVALive - 7041 The Problem to Slow Down You (回文树)

    https://vjudge.net/problem/UVALive-7041 题意 给出两个仅包含小写字符的字符串 A 和 B : 求:对于 A 中的每个回文子串,B 中和该子串相同的子串个数的总和 ...

  4. 设置 Visual Studio IIS Express 站点局域网访问

    Ø  Visual Stuido 的 IIS Express运行一个网站时,默认地址是这样的:http://localhost:23167/Cache/Three,其中 localhost 表示本机, ...

  5. oracle 查看后台正在执行的脚本

    select username,lockwait,status,machine,program from v$session where sid in (select session_id from ...

  6. 前段js的各种弹出框

    artDialog 首页 > 文档与示例 artDialog —— 经典的网页对话框组件,内外皆用心雕琢. 支持普通与 12 方向气泡状对话框 完善的焦点处理,自动焦点附加与回退 支持 ARIA ...

  7. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  8. List与逗号分隔的字符串相互转换

    如果程序员想实现某种功能,有两条路可以走.一条就是自己实现,一条就是调用别人的实现,别人的实现就是所谓的API.而且大多数情况下,好多“别人”都实现了这个功能.程序员有不得不在这其中选择.大部分情况下 ...

  9. JAVA百度过的异常(1)

    1.---无法解析类型 javax.servlet.http.HttpServletRequest.从必需的 .class 文件间接引用了它 The type javax.servlet.http.H ...

  10. MongoDB 学习手册 - CURD

    mongoDB 增加数据 // mongoDB 增加数据: //新增数据insert( 字典 ) 表示插入一条数据,insert([字典]) 表示插入多条数据 // db.text01.insert( ...