[AGC040E]Prefix Suffix Addition
Prefix Suffix Addition
题解
首先,对于这道题,我们一个比较容易的想法是将整个序列拆成一个序列BBB和一个序列CCC,满足Ai=Bi+CiA_i=B_i+C_iAi=Bi+Ci。
我们对于序列BBB中的数执行操作111,序列CCC中的数执行操作222。
这样,我们就能将对一个序列进行两种操作变为对两个序列执行方向不同的一种操作。
我们观察一个序列的情况,如果我们被允许从一端开始减去一个递增序列最少多少次能把它减完。
可以发现,这样减完序列AAA的答案为∑i=1n[Ai>Ai+1]\sum_{i=1}^{n} [A_{i}>A_{i+1}]∑i=1n[Ai>Ai+1]。
显然,我们会尝试从ana_nan到a1a_1a1,不断把数减为000,在ai+1a_{i+1}ai+1减到000时,aia_iai被减的值不会超过ai+1a_{i+1}ai+1。如果ai+1⩾aia_{i+1}\geqslant a_iai+1⩾ai,那么减完ai+1a_{i+1}ai+1时也可以把aia_iai减完,否则需要多执行一次操作。
反过来操作同理,所以最后的答案为∑i=0n[Bi>Bi+1]+[Ci<Ci+1]\sum_{i=0}^{n} [B_i>B_{i+1}]+[C_i<C_{i+1}]∑i=0n[Bi>Bi+1]+[Ci<Ci+1]。
我们可以考虑对这东西进行dpdpdp。
定义dpi,jdp_{i,j}dpi,j表示Bi=Ai−j,Ci=jB_i=A_i-j,C_i=jBi=Ai−j,Ci=j时前缀所产生的最小贡献。
显然,我们是比较容易地写出它的dpdpdp转移式的,
dpi,j=mink=0Ai−1(dpi−1,k+[j>k]+[Ai−j<Ai−1−k])dp_{i,j}=\min_{k=0}^{A_{i-1}}\left(dp_{i-1,k}+[j>k]+[A_i-j<A_{i-1}-k]\right) dpi,j=k=0minAi−1(dpi−1,k+[j>k]+[Ai−j<Ai−1−k])
当然,直接这样转移是O(nA)O\left(nA\right)O(nA)的,显然不行,考虑优化。
我们可以从上面的转移式发现一个性质:
- ∀j<k(j,k∈[0,Ai]),dpi,k−dpi,j∈[0,2]\forall j<k(j,k\in[0,A_{i}])\,,\,dp_{i,k}-dp_{i,j}\in[0,2]∀j<k(j,k∈[0,Ai]),dpi,k−dpi,j∈[0,2]
这相当于说它是单调不降的并且最大值与最小值差不会超过222。
单调不降这点是比较好理解的,对于j<k(j,k∈[0,Ai])j<k(j,k\in [0,A_i])j<k(j,k∈[0,Ai]),如果kkk的最优转移点为pkp_kpk的话,那么我们先假令jjj也从pkp_kpk转移过来有:
[j>pk]+[Ai−j<Ai−1−pk]⩽[k>pk]+[Ai−k<Ai−1−pk]⇔[j>pk]−[k>pk]+[Ai−j<Ai−1−pk]−[Ai−k<Ai−1−pk]⩽0⇔[j⩽pk<k]+[Ai−k⩽Ai−1−pk⩽Ai−j]⩾0[j>p_k]+[A_{i}-j<A_{i-1}-p_k]\leqslant [k>p_k]+[A_i-k<A_{i-1}-p_k]\\ \Leftrightarrow[j>p_k]-[k>p_k]+[A_{i}-j<A_{i-1}-p_k]-[A_i-k<A_{i-1}-p_k]\leqslant 0\\ \Leftrightarrow[j\leqslant p_k<k]+[A_i-k\leqslant A_{i-1}-p_{k}\leqslant A_i-j]\geqslant0 [j>pk]+[Ai−j<Ai−1−pk]⩽[k>pk]+[Ai−k<Ai−1−pk]⇔[j>pk]−[k>pk]+[Ai−j<Ai−1−pk]−[Ai−k<Ai−1−pk]⩽0⇔[j⩽pk<k]+[Ai−k⩽Ai−1−pk⩽Ai−j]⩾0显然,这个等式是恒成立的。
而jjj还可以有更好的转移点,所以还可能更小。
而差值不超过222这点也非常好理解,如果jjj是从pjp_jpj转移过来,那么如果kkk也从这转移的话,最多就多两个111,加起来显然不会超过222。
所以,事实上我们的dpjdp_jdpj是一个分三段的分段函数,我们的转移实际上就是在对这个分段函数进行转移。
我们可以记录(xi,li,ri)(x_i,l_i,r_i)(xi,li,ri)表示这个三元组,表示对于dpi,j=x+[j>li]+[j>ri]dp_{i,j}=x+[j>l_i]+[j>r_i]dpi,j=x+[j>li]+[j>ri]。
转移到dpi+1dp_{i+1}dpi+1后的最小值xxx仍然可以在dpi+1,0dp_{i+1,0}dpi+1,0处取得,我们考虑计算dpi+1,0dp_{i+1,0}dpi+1,0的值。
显然dpi,0⩽dpi+1,0⩽dpi,0+1dp_{i,0}\leqslant dp_{i+1,0}\leqslant dp_{i,0}+1dpi,0⩽dpi+1,0⩽dpi,0+1,只有[0>k][0>k][0>k]显然不成立,只有[Ai−0⩽Ai−1−k][A_i-0\leqslant A_{i-1}-k][Ai−0⩽Ai−1−k]会贡献到答案。
对于dpidp_idpi这一层,最好的转移点显然是dpi,lidp_{i,l_i}dpi,li和dpi,ridp_{i,r_i}dpi,ri,它们在自己的层次里都使得CiC_iCi最大。
对于dpi+1,0dp_{i+1,0}dpi+1,0,我们就只看dpi,ldp_{i,l}dpi,l,有dpi+1,0=dpi,0+[Ai<Ai−1−li]dp_{i+1,0}=dp_{i,0}+[A_i<A_{i-1}-l_i]dpi+1,0=dpi,0+[Ai<Ai−1−li],这样就得到了xi+1x_{i+1}xi+1。
之后的li+1,ri+1l_{i+1},r_{i+1}li+1,ri+1可以用类似的方法得到,我们就相对于上面的每一段,建立出关于li+1l_{i+1}li+1和ri+1r_{i+1}ri+1的不等式组,解出答案。
容易发现,这样的转移单次是O(1)O\left(1\right)O(1)的,答案就是xn+[an>ln]x_n+[a_n>l_n]xn+[an>ln]。
总时间复杂度O(n)O\left(n\right)O(n)。
源码
代码其实很短
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> pii;
#define MAXN 200005
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
#define lowbit(x) (x&-x)
const int mo=998244353;
const int inv2=5e8+4;
const int jzm=2333;
const int zero=15;
const int INF=0x3f3f3f3f;
const double Pi=acos(-1.0);
const double eps=1e-9;
const int orG=3,ivG=332748118;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,a[MAXN];
struct range{int x,l,r;}dp[MAXN];
int main(){read(n);for(int i=1;i<=n;i++)read(a[i]);dp[0]=(range){0,0,0};for(int i=1;i<=n;i++){int l=dp[i-1].l,r=dp[i-1].r;if(a[i]>=a[i-1]-l)dp[i].x=dp[i-1].x,dp[i].l=min(min(l,a[i]-a[i-1]+l),a[i]),dp[i].r=min(max(max(l,a[i]-a[i-1]+l),min(r,a[i]-a[i-1]+r)),a[i]);else dp[i].x=dp[i-1].x+1,dp[i].r=a[i],dp[i].l=min(max(max(l,a[i]-a[i-1]+l),min(r,a[i]-a[i-1]+r)),a[i]);}printf("%d\n",dp[n].x+(a[n]>dp[n].l));return 0;
}
谢谢!!!
[AGC040E]Prefix Suffix Addition相关推荐
- mybatis之trim prefix= suffix= suffixOverrides= prefixOverrides=/trim
转载自 https://blog.csdn.net/qq_33054511/article/details/70490046 1.<trim prefix="" suffix ...
- mybatis中prefix,suffix,prefixOverrides,suffixOverrides用法解释
<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=" ...
- SQL删除空格Trim函数(RTrim、LTrim)与<trim prefix=““ suffix=““ suffixOverrides=““ prefixOverrides=““></trim>
一.SQL删除数据空格函数(Trim.RTrim.LTrim) 1.Trim()函数:前后空格 用来删除数据左右两边(开始和结尾处)的空格. 2.RTrim()函数:后面空格 用来删除数据右边(结尾处 ...
- 记一次BUG:File.createTempFile(prefix, suffix);
背景 在之前做文件上传与下载时,在这里记录一个遇到下载文件的坑,希望大家看了可以避免. BUG来源 背景:在做下载文件时,后台使用的是选择response输出到客户端,通过设置请求头,进行下载: re ...
- 【Java代码】实现字符串转数据库的 inStr【使用 JDK8 stream.collect(Collectors.joining(delimiter, prefix, suffix)) 实现】
why 有不少这样的情况,前端会传筛选条件,给到后端的时候是个 conditionStr ,如果您用的是 mybatis-plus 的 API 那么直接 split 一下就可以使用,如果不是,那就需要 ...
- Mybatis的prefix和suffix使用
语法格式 <trim prefix="" suffix="" suffixOverrides="" prefixOverrides=& ...
- MyBatis的<trim></trim>标签及prefix,suffix,suffixOverrides
开发中常见用法 <insert id="insertSelective" parameterType="com.lwx.rental.core.db.po.Rent ...
- Google Test(Primer)(三)——断言
Assertions <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /& ...
- Java经典代码工具类2
转自: https://www.iteye.com/blog/wuhaidong-1668689 package com.common.file; import java.io.File; impor ...
最新文章
- Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem G. k-palindrome dp
- 【JavaScript】jQuery绑定事件
- linux系统虚拟化测试,网络性能与磁盘测试 - Linux虚拟化性能PK:Ubuntu系统6大版本_Linux新闻_Linux公社-Linux系统门户网站...
- 掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地上篇
- 如何构建GFS分布式存储平台?理论+实操!
- 走访近20家代工厂后:近千块的大牌T恤,成本只要几十块
- js操作table中tr的顺序,实现上移下移一行的效果
- python学习 day6 (3月7日)
- git github gitlib gitlab
- web测试常用的用例及知识
- 《剑指offer》面试题的Python实现
- 2016级算法期末上机-H.难题·AlvinZH's Fight with DDLs III
- Ubuntu ufw 取消 网关到 224.0.0.1 multicast 日志
- 科技部再公布网络安全等10项国家重点研发计划
- 微信使用OD逆向HOOK的一些心得
- Robotframework基础篇(一):使用ride编辑器
- Proteus做C51最小系统的仿真
- 域名解析指向详细操作(图解)
- Outlook 2007无法连接Exchange 2007
- Linux ssh 密钥的生成与使用
热门文章
- ttf字库瘦身,只保留自己想要的字
- Memcache 键值key的格式和类型
- lvgl 显示图片示例
- 一本非专业应届生成功斩获华为22k OFFER,如何实现
- 南京邮电大学计算机学院研究生录取通知书,南京邮电大学2017年硕士研究生录取通知书发放通知...
- 已解决error: legacy-instal1-failure
- 局域网Git服务器和客户端的搭建和简单使用
- fidder+Xposed JustTruestMe框架安装,解决网络错误
- 多测师肖sir_高级讲师_第2个月第28讲解jmeter性能指标详解
- Java基础语法_循环结构【多测师_何sir】