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 ...
随机推荐
- EMC测试国家标准GB/T 17626
转载: 详解EMC测试国家标准GB/T 17626 - whik - 博客园 (cnblogs.com)
- 初学python-day2 字符串格式化1
- Java字符串转数字和数字转字符串
int转String有3种方式 (1)num + "" (2)String.valueOf(num) (3)Integer.toString(num) String转int有2种方 ...
- Linux线程互斥学习笔记--详细分析
一.互斥锁 为啥要有互斥? 多个进程/线程执行的先后顺序不确定,何时切出CPU也不确定. 多个进程/线程访问变量的动作往往不是原子的. 1. 操作步骤 (1)创建锁 // 创建互斥锁mutex pth ...
- Ubuntu virtualenv 创建 python3 虚拟环境 激活 退出
首先默认安装了virtualenv 创建python3虚拟环境 your-name@node-name:~/virtual_env$ virtualenv -p /usr/bin/python3 py ...
- 第04课 OpenGL 旋转
旋转: 在这一课里,我将教会你如何旋转三角形和四边形.左图中的三角形沿Y轴旋转,四边形沿着X轴旋转. 上一课中我教给您三角形和四边形的着色.这一课我将教您如何将这些彩色对象绕着坐标轴旋转.其实只需在上 ...
- Pod 健康检查和服务可用性检查
Kubernetes 对 Pod 的健康状态可以通过两类探针来检查:LivenessProbe 和 ReadinessProbe,kubelet 定期执行这两类探针来针对容器的健康状况. Livene ...
- 『学了就忘』Linux基础命令 — 27、搜索操作相关命令
目录 1.whereis命令 2.which命令 3.locate命令 1.whereis命令 whereis是搜索系统命令的命令,也就是说,whereis命令不能搜索普通文件,而只能搜索系统命令. ...
- Java 网络编程 - 总结概述
IP地址 IP地址IntAddress 唯一定位一台网络上的计算机 127.0.0.1:本地localhost IP地址的分类 ipV4/ipV6 ipV4:127.0.0.1,4个字节组成:0~25 ...
- SpringBoot 中发布ApplicationEventPublisher,监听ApplicationEvent 异步操作
有这么一个业务场景:当用户注册后,发送邮件到其邮箱提示用户进行账号激活,且注册成功的同时需要赠送新人用户体验卡券. 业务有了,那么问题也就来了. What? 问题....问题?我听说你有问题? 来拔刀 ...