Codeforces 739C - Alyona and towers(线段树)
可能有人会问我为什么为这道 *2500 的 D1C 写题解,我觉得大概是想要在写题解数量上 dd ycx 吧,因为 ycx 到目前为止写了 143 篇题解,而这也是我的第 143 篇题解(((
大概和 CF1149C Tree Generator 比较像?做过那题这题基本可以一眼秒了(
线段树。每个区间维护以下八个值:
- 区间第一个元素的值 \(fst\)
- 区间最后一个元素的值 \(lst\)
- 区间长度 \(len\)
- 以左端点为开头的最长下降前缀的长度 \(llen\)
- 以右端点为开头的最长上升后缀的长度 \(rlen\)
- 以左端点为开头的先上升再下降的最长前缀长度 \(l\_tower\)
- 以右端点为结尾的先上升再下降的最长前缀长度 \(r\_tower\)
- 这段区间中最长的先上升后下降子序列的长度 \(mx\)
考虑合并左右两个区间:
- \(fst\) 就直接继承左儿子的 \(fst\) 即可
- \(lst\) 就直接继承右儿子的 \(lst\) 即可
- \(len\) 就直接将左右儿子的 \(len\) 加起来即可
- \(llen\) 分两种情况,如果左儿子的 \(llen\) 就等于其 \(len\),并且左儿子的 \(lst\) 大于右儿子的 \(fst\),那么该节点的 \(llen\) 等于左右节点的 \(llen\) 之和。否则该节点的 \(llen\) 等于左儿子的 \(llen\)。\(rlen\) 也同理
- \(l\_tower\) 分三种情况,如果左儿子本身就是上升序列,即左儿子的 \(rlen\) 等于其 \(len\),并且左儿子的 \(lst\) 小于右儿子的 \(fst\),那么 \(l\_tower\) 就等于左儿子的 \(rlen\) 与右儿子的 \(l\_tower\) 的和。如果左儿子的 \(l\_tower\) 等于其 \(len\),并且左儿子的 \(lst\) 大于右儿子的 \(fst\),那么 \(l\_tower\) 就等于左儿子的 \(len\) 与右儿子的 \(llen\) 之和。否则 \(l\_tower\) 等于左儿子的 \(l\_tower\)。\(r\_tower\) 也同理。
- \(mx\) 分四种情况,首先它可以从左右儿子的 \(mx\) 分别继承来,即它首先等于左右儿子 \(mx\) 的较大者。其次如果左儿子的 \(lst\) 小于右儿子的 \(fst\),那么 \(mx\) 可以用左儿子的 \(rlen\) 与右儿子的 \(l\_tower\) 之和更新;如果左儿子的 \(lst\) 大于右儿子的 \(fst\),那么 \(mx\) 可以用左儿子的 \(r\_tower\) 与右儿子的 \(llen\) 之和更新
写个结构体维护一下即可。区间修改就直接打个标记。
芜湖~做完了,记得开 long long,复杂度线对。
const int MAXN=3e5;
int n,qu,a[MAXN+5];
struct data{
ll fst,lst;int len,llen,rlen,l_tower,r_tower,mx;
data(){fst=lst=len=llen=rlen=l_tower=r_tower=mx=0;}
data(int _fst,int _lst,int _len,int _llen,int _rlen,int _l_tower,int _r_tower,int _mx):
fst(_fst),lst(_lst),len(_len),llen(_llen),rlen(_rlen),l_tower(_l_tower),r_tower(_r_tower),mx(_mx){}
friend data operator +(data a,data b){
data c;
c.fst=a.fst;c.lst=b.lst;c.len=a.len+b.len;
c.llen=(a.llen==a.len&&a.lst>b.fst)?(a.llen+b.llen):a.llen;
c.rlen=(b.rlen==b.len&&a.lst<b.fst)?(b.rlen+a.rlen):b.rlen;
c.l_tower=(a.rlen==a.len&&a.lst<b.fst)?(a.l_tower+b.l_tower):
((a.l_tower==a.len&&a.lst>b.fst)?(a.l_tower+b.llen):(a.l_tower));
c.r_tower=(b.llen==b.len&&a.lst>b.fst)?(b.r_tower+a.r_tower):
((b.r_tower==b.len&&a.lst<b.fst)?(b.r_tower+a.rlen):(b.r_tower));
c.mx=max(a.mx,b.mx);
if(a.lst>b.fst) c.mx=max(c.mx,a.r_tower+b.llen);
if(a.lst<b.fst) c.mx=max(c.mx,a.rlen+b.l_tower);
return c;
}
};
struct node{int l,r;ll lz;data v;} s[MAXN*4+5];
void pushup(int k){s[k].v=s[k<<1].v+s[k<<1|1].v;}
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;if(l==r){s[k].v=data(a[l],a[l],1,1,1,1,1,1);return;}
int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}
void pushdown(int k){
if(s[k].lz){
s[k<<1].lz+=s[k].lz;s[k<<1].v.fst+=s[k].lz;s[k<<1].v.lst+=s[k].lz;
s[k<<1|1].lz+=s[k].lz;s[k<<1|1].v.fst+=s[k].lz;s[k<<1|1].v.lst+=s[k].lz;
s[k].lz=0;
}
}
void modify(int k,int l,int r,int x){
if(l<=s[k].l&&s[k].r<=r){
s[k].lz+=x;s[k].v.fst+=x;s[k].v.lst+=x;
return;
} pushdown(k);int mid=s[k].l+s[k].r>>1;
if(r<=mid) modify(k<<1,l,r,x);
else if(l>mid) modify(k<<1|1,l,r,x);
else modify(k<<1,l,mid,x),modify(k<<1|1,mid+1,r,x);
pushup(k);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);scanf("%d",&qu);
while(qu--){
int l,r,v;scanf("%d%d%d",&l,&r,&v);
modify(1,l,r,v);printf("%d\n",s[1].v.mx);
}
return 0;
}
Codeforces 739C - Alyona and towers(线段树)的更多相关文章
- Codeforces 739C Alyona and towers 线段树
Alyona and towers 这个题写起来真的要人命... 我们发现一个区间被加上一个d的时候, 内部的结构是不变的, 改变的只是左端点右端点的值, 这样就能区间合并了. 如果用差分的话会简单一 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- codeforces 22E XOR on Segment 线段树
题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...
- Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- Codeforces 444C DZY Loves Colors(线段树)
题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值. 解题思路:线段树模板题. #inclu ...
- Codeforces 85D Sum of Medians(线段树)
题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...
- [Codeforces]817F. MEX Queries 离散化+线段树维护
[Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...
随机推荐
- Less-32 宽字节
<!-- 下午整了半天Less-29~31,愣是没调好jsp环境,只好跳过. 难受.jpg !--> Less-32: 核心语句: 各种回显均存在. 第一句话指定了字符集为gbk. che ...
- MySQL复习(二)MySQL基本数据类型
MySQL基本数据类型 常用的字段类型大致可以分为数值类型.字符串类型.日期时间类型三大类 1. 数值类型 数值类型可以分为整型.浮点型.定点型三小类. 1.1 整型 (tiny:极小的, small ...
- 实用小技巧:Notepad++直接连接Linux
实用小技巧:Notepad++直接连接Linux 前言 号称编辑器之神的Vim对于只会用几个基础操作的本人而言,在编辑一些大型文本有那么些力不从心: 平时都是通过Xftp拖到本地,修改完后再覆盖回去: ...
- 【二食堂】Beta - Scrum Meeting 8
Scrum Meeting 8 例会时间:5.22 20:00~20:10 进度情况 组员 当前进度 今日任务 李健 1. UI优化已经完成,顺带修复了一点小bug.issue 1. 文本导入.保存部 ...
- Spring Security Resource Server的使用
Spring Security Resource Server的使用 一.背景 二.需求 三.分析 四.资源服务器认证流程 五.实现资源服务器 1.引入jar包 2.资源服务器配置 3.资源 六.测试 ...
- Linux文件IO操作
来源:微信公众号「编程学习基地」 目录 文件操作 Linux文件类型 Linux文件权限 修改文件权限 Linux error 获取系统调用时的错误描述 打印错误信息 系统IO函数 open/clos ...
- Linux 显示ip、dns、网关等命令
在新版的ubuntu 终端里输入命令nm-tool, 想查看网络参数设置, 没想到却返回如下内容: 未找到 'nm-tool' 命令,您要输入的是否是: 命令 'dm-tool' 来自于包 'l ...
- shell 脚本控制命令的执行顺序
&&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...
- vim 脚本,自动添加文件头部信息
相信很多人编写脚本的时候都会在脚本头部写一些信息,记录文件生成时候,生成人姓名等 建议在自己的家目录下的 .vimrc 文件 下添加以下内容 [ autocmd BufNewFile *.sh exe ...
- 黑客是如何利用DNS域传送漏洞进行渗透与攻击的?
一.DNS域传送 DNS :Domain Name System 一个保存IP地址和域名相互映射关系的分布式数据库,重要的互联网基础设施,默认使用的TCP/UDP端口号是53 常见DNS记录类型: 1 ...