【SCOI2010】序列操作
各种繁琐的线段树标记操作。。。赤裸裸的码农题。
调了一个晚上,最后写篇题解。
题解亮点:代码短,~~跑得慢(连第一页都没挤进去)~~
其实我跟你们说啊,代码短是好事~~(这里不是说压行好,我的代码不压行也没那么长)~~,因为代码短好调啊,几个类似的语句写个函数,既满足了懒人需要(减少码量),而且也让代码思路清晰,没有那么杂乱了。
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】序列操作的更多相关文章
- bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...
- BZOJ 1858: [Scoi2010]序列操作( 线段树 )
略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...
- bzoj1858[Scoi2010]序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 3079 Solved: 1475[Submit][Statu ...
- BZOJ_1858_[Scoi2010]序列操作_线段树
BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...
- 【题解】Luogu P2572 [SCOI2010]序列操作
原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...
- P2572 [SCOI2010]序列操作
对自己 & \(RNG\) : 骄兵必败 \(lpl\)加油! P2572 [SCOI2010]序列操作 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要 ...
- BZOJ1858 [Scoi2010]序列操作(线段树)
题目链接 [Scoi2010]序列操作 考验代码能力的一道好题. 思想还是很简单的(直接上线段树),但是比较难写. #include <bits/stdc++.h> using names ...
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 3397 Solved: 1624 [Submit][Statu ...
- SCOI2010 序列操作
2421 序列操作 http://codevs.cn/problem/2421/ 2010年省队选拔赛四川 题目描述 Description lxhgww最近收到了一个01序列,序列里面包含了n个 ...
随机推荐
- C#设计模式(10)——桥接模式
1.桥接模式介绍 桥接模式用于将抽象化和实现化解耦,使得两者可以独立变化.在面向对象中用通俗的话说明:一个类可以通过多角度来分类,每一种分类都可能变化,那么就把多角度分离出来让各个角度都能独立变化,降 ...
- FeignClient调用POST请求时查询参数被丢失的情况分析与处理
前言 本文没有详细介绍 FeignClient 的知识点,网上有很多优秀的文章介绍了 FeignCient 的知识点,在这里本人就不重复了,只是专注在这个问题点上. 查询参数丢失场景 业务描述: 业务 ...
- udp_connect函数
#include <netdb.h> #include <stdlib.h> #include <unistd.h> #include <string.h&g ...
- 八、文件IO——存储映射
8.1 存储映射介绍 8.1.1 概念 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. 文件操作部分映射到虚拟内存的一块区域,我们对虚拟内存映射的那块区域 ...
- pyqt5模块介绍
python各种库介绍 https://wiki.python.org/moin/GuiProgramming PyQt5.QtWidgets 包含控件 PyQt5.QtGui 图 ...
- webwork框架
以前都没有用过WebWork这个框架,只是听说过.没想到现在要用,所以就自学了一下.做了个小例子给大家分享下中间遇到的苦难和经验. 准备工作:首先要去下载WebWork框架的开发包.我用的2.2.6版 ...
- sqlserver分组统计合并
---分组partition by;统计:Count();合并:for xml path('') with cte as( select COUNT(t2.Id) OVER(PARTITION BY ...
- 《从Paxos到Zookeeper:分布式一致性原理与实践》第一章读书笔记
第一章主要介绍了计算机系统从集中式向分布式系统演变过程中面临的挑战,并简要介绍了ACID.CAP和BASE等经典分布式理论,主要包含以下内容: 集中式的特点 分布式的特点 分布式环境的各种问题 ACI ...
- 帝国cms建站方法和知识点
帝国cms建站方法和知识点 1. 首先在帝国cms网站上下载模板系统.根据模板系统上的提示,将指定的目录文件放在指定的位置.然后进行安装.后台管理系统的命名设置.数据库的设置等等. 2. 安装完成 ...
- Android逆向基础----APK文件结构
参考这个博客 http://www.cnblogs.com/wangtianxj/archive/2010/06/13/1757639.html http://blog.csdn.net/bupt07 ...