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 ...
随机推荐
- k8s replicaset controller 分析(3)-expectations 机制分析
replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...
- [敏捷软工团队博客]Beta阶段项目展示
团队成员简介和个人博客地址 头像 姓名 博客园名称 自我介绍 PM 测试 前端 后端 dzx 秃头院的大闸蟹 大闸蟹是1706菜市场里无菜可卖的底层水货.大闸蟹喜欢音乐(但可惜不会),喜欢lol(可惜 ...
- [no code][scrum meeting] Beta 3
$( "#cnblogs_post_body" ).catalog() 例会时间:5月15日11:30,主持者:肖思炀 下次例会时间:5月16日11:30,主持者:伦泽标 一.工作 ...
- 了解 js 堆内存 、栈内存 。
js中的堆内存与栈内存 在js引擎中对变量的存储主要有两种位置,堆内存和栈内存. 和java中对内存的处理类似,栈内存主要用于存储各种基本类型的变量,包括Boolean.Number.String.U ...
- (1)Zookeeper在linux环境中搭建集群
1.简介 ZooKeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper的架构通过冗余服务实现高可用性.Zookeeper ...
- netty系列之:搭建客户端使用http1.1的方式连接http2服务器
目录 简介 使用http1.1的方式处理http2 处理TLS连接 处理h2c消息 发送消息 总结 简介 对于http2协议来说,它的底层跟http1.1是完全不同的,但是为了兼容http1.1协议, ...
- linux运维思想
1.安装部署某个服务或者研究某个知识点时,宁可花大量时间,也需要尽量将该服务搞透,后续再遇到相关问题时你会发现这为你节省的时间将远远比你当时花的时间多. 2.安装部署时,做好记录,发本地记录并发表博文 ...
- django的增删改查
前置条件: 已有一个model (tbl_user) ,用户表 1.查询 # 查询用户表 username是cx的数据 user_object = tbl_user.objects.filter(us ...
- Python Nose 自动化测试框架介绍
文章目录 1. unittest 简介 1.1 python 单元测试 1.2 unittest 测试框架 1.3 默认模式 1.4 手工模式 2. nose 扩展框架 2.1 `nose` 的安装和 ...
- Visual Studio中使用Macros插件给代码添加注释、时间和以及自动脚本
title: Visual Studio中使用Macros插件给代码添加注释.时间和以及自动脚本 date: 2020-09-11 sidebarDepth: 2 tags: 代码 Visual st ...