Codeforces 1500F - Cupboards Jumps(set)
nb tea!!!111
首先很显然的一件事是对于三个数 \(a,b,c\),其最大值与最小值的差就是三个数之间两两绝对值的较大值,即 \(\max(|a-b|,|b-c|,|c-a|)\),因此我们不妨从差分序列的角度解决这个问题。对于原序列 \(h\),我们假设其差分序列 \(d_i=h_{i+1}-h_i\),那么 \(\max(h_i,h_{i+1},h_{i+2})-\min(h_i,h_{i+1},h_{i+2})=\max(|h_{i+1}-h_{i}|,|h_{i+2}-h_{i+1}|,|h_{i+2}-h_i|)\),又 \(h_{i+2}-h_i=d_i+d_{i+1}\),因此我们可以得到 \(w_i=\max(|d_i|,|d_{i+1}|,|d_i+d_{i+1}|)\)
思考到这里我们就能够想出一个非常 naive 的 DP,\(dp_{i,x}\) 表示考虑到前 \(i\) 个数,\(|d_i|=x\) 是否可行,转移就枚举下一个数 \(d_{i+1}=y\),那么 \(dp_{i,x}\) 能转移到 \(dp_{i+1,y}\) 的充要条件是 \(x=w_i\lor y=w_i\lor x+y=w_i\) 且 \(x,y\le w_i\),这样暴力 DP 是 \(\mathcal O(nC^2)\) 的,不知道能拿多少分(大雾)。考虑进行一点点优化,注意到我们 \(dp_{i,x}=1\) 的 \(x\) 肯定是成段分布的对吧,因此我们考虑每一段在转移前后会变成什么,我们假设考虑到 \(i\) 时,满足 \(dp_{i,x}=1\) 的 \(x\) 组成的集合为 \(S\),那么:
- 如果 \(w_i\in S\),那么 \(\forall y\in[0,w_i]\) 均有 \(dp_{i+1,y}=1\),具体方案就是令 \(d_i=w_i,d_{i+1}=-y\)。
- 如果到现在还没有判定出无解,也即 \(\exists x\in S,s.t.x<w_i\)(因为 \(>w_i\) 肯定不合法,并且由于该情况不同于上一种情况所以 \(w_i\notin S\)),那么有 \(dp_{i+1,w_i-x}=1\),具体方案就是 \(d_i=x,d_{i+1}=w_i-x\),同时也有 \(dp_{i+1,w_i}=1\),具体方案就是 \(d_i=-x,d_{i+1}=w_i\)。也就是说如果 \(w_i\notin S\),那么所有点都会变为 \(w_i-x\),同时加入一个新点 \(w_i\)
因此如果我们维护这些连续段组成的集合,那么每次可以暴力 \(\mathcal O(n)\) 转移每个连续段,因此我们复杂度就降到了 \(\mathcal O(n^2)\)(虽然还是一脸过不去的亚子)
考虑进一步优化,我们注意到这个过程很特别,因为每次如果 \(w_i\notin S\),那么新增进来的肯定是一个个单点,而区间自始至终都只有一个,也就是说我们可以不考虑一一反转这个单点,而是翻转整个数轴,也就是说我们开一个 set
维护这些单点在最一开始的数轴上的位置,然后维护两个值 \(L,R\) 表示当前区间的两个端点在最一开始的数轴上的位置,然后每次检验现在坐标为 \(w_i\) 的位置在最一开始的数轴上的位置是否属于这个集合与区间的并,如果属于则说明 \(x\in S\),那么我们就把数轴还原成一开始的样子,把 set
清空并把区间最右端点设为 \(0\) 和 \(w_i\),否则我们就记录一下区间是否被翻转,即 \(+x\) 方向是否已经变为 \(-x\),记这个标记为 \(flg\),以及数轴的偏移量 \(dlt\),那么我们就设 \(flg:=1-flg,dlt:=w_i-dlt\),然后把 \(w_i\) 加入集合。如果某一步 \(L\) 在现在数轴上对应的位置 \(>R\) 在现在数轴上对应的位置且 \(S=\varnothing\) 那么无解。
接下来考虑怎样找出合法的方案,我们不妨首先找出任意一个 \(c_i\in S\),其中 \(S\) 表示扫描到第 \(i\) 步时合法的 \(x\) 组成的集合,那么我们考虑这样构造出 \(|d_i|\),从最后一个元素开始,我们令 \(|d_{n+1}|=c_{n+1}\),然后如果 \(|d_{n+1}|=w_n\) 那么我们直接令 \(|d_n|=c_n\) 就好了,否则如果 \(c_n=w_n\) 说明 \(|d_n|\) 设为 \(w_n\) 是合法的选择,我们干脆就令 \(|d_n|=w_n\),否则我们就只能令 \(|d_{n}|=w_n-|d_{n+1}|\)。然后我们可以根据 \(|d_n|\) 构造出 \(d_n\),具体方案就是从右往左扫一遍,如果 \(|d_i|+|d_{i+1}|\ne w_i\) 就将 \(d_i\) 变为其相反数。
时间复杂度 \(n\log n\)。
const int MAXN=1e6;
int n;ll C,w[MAXN+5],can[MAXN+5],d[MAXN+5],s[MAXN+5],l,r;
set<ll> st;int flg;ll dlt;
ll gettrs(ll x){return flg?(dlt-x):(dlt+x);}
ll getori(ll x){return flg?(dlt-x):(x-dlt);}
int main(){
scanf("%d%lld",&n,&C);l=0;r=C;
for(int i=1;i<=n-2;i++) scanf("%lld",&w[i]);
for(int i=1;i<=n-2;i++){
ll L=getori(0),R=getori(w[i]);if(L>R) L^=R^=L^=R;
chkmax(l,L);chkmin(r,R);
while(!st.empty()&&(*st.begin())<L) st.erase(st.begin());
while(!st.empty()&&(*st.rbegin())>R) st.erase(st.find(*st.rbegin()));
if(l>r&&st.empty()) return puts("NO"),0;
if(st.find(getori(w[i]))!=st.end()||(l<=getori(w[i])&&getori(w[i])<=r)){
st.clear();l=0;r=can[i]=w[i];flg=dlt=0;continue;
} if(l<=r) can[i]=gettrs(l);else can[i]=gettrs(*st.begin());
flg^=1;dlt=w[i]-dlt;st.insert(getori(w[i]));
} if(l<=r) d[n-1]=gettrs(l);else d[n-1]=gettrs(*st.begin());
for(int i=n-2;i;i--){
if(can[i]==w[i]) d[i]=w[i];
else if(d[i+1]==w[i]) d[i]=can[i];
else d[i]=w[i]-d[i+1];
} ll t=1;
// for(int i=1;i<=n-1;i++) printf("%lld%c",d[i]," \n"[i==n-1]);
for(int i=n-2;i;i--){
if(abs(d[i])+abs(d[i+1])!=w[i]) t=-t;
d[i]=t*d[i];
} ll mn=1e18;puts("YES");
for(int i=1;i<=n;i++) s[i]=s[i-1]+d[i-1],chkmin(mn,s[i]);
for(int i=1;i<=n;i++) printf("%lld%c",s[i]-mn," \n"[i==n]);
return 0;
}
Codeforces 1500F - Cupboards Jumps(set)的更多相关文章
- Codeforces I. Producing Snow(优先队列)
题目描述: C. Producing Snow time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Codeforces Gym101341K:Competitions(DP)
http://codeforces.com/gym/101341/problem/K 题意:给出n个区间,每个区间有一个l, r, w,代表区间左端点右端点和区间的权值,现在可以选取一些区间,要求选择 ...
- 【CodeForces - 651C 】Watchmen(map)
Watchmen 直接上中文 Descriptions: 钟表匠们的好基友马医生和蛋蛋现在要执行拯救表匠们的任务.在平面内一共有n个表匠,第i个表匠的位置为(xi, yi). 他们需要安排一个任务计划 ...
- [Codeforces 274E]:Mirror Room(模拟)
题目传送门 题目描述 有一个$n\times m$的格子图,其中有一些是黑色的,另一些为白色.从某个白色格子的中心点向左上($NW$),左下($SW$),右上($NE$),右下($SE$)四个方向中的 ...
- CodeForces - 1162E Thanos Nim (博弈论)
Alice and Bob are playing a game with nn piles of stones. It is guaranteed that nn is an even number ...
- Codeforces Round #627 (Div. 3) C - Frog Jumps(逻辑)
题意: 有一个每个单元标明移动方向的长为n的序列,每次移动不能超过距离k,问能够从0移动到n+1的k的最小值. 思路: k=最长连续L序列长度+1. #include <bits/stdc++. ...
- CodeForces 540C Ice Cave (BFS)
http://codeforces.com/problemset/problem/540/C Ice Cave Time Limit:2000MS Memory Limit:262 ...
- codeforces 711C Coloring Trees(DP)
题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...
- codeforces#1154F. Shovels Shop (dp)
题目链接: http://codeforces.com/contest/1154/problem/F 题意: 有$n$个物品,$m$条优惠 每个优惠的格式是,买$x_i$个物品,最便宜的$y_i$个物 ...
随机推荐
- JVM详解(六)——对象的实例化、内存布局与访问定位
一.对象的实例化 1.创建对象的方式 2.创建对象的步骤 脑图:https://www.processon.com/view/link/61701a927d9c087040525226 3.对象属性赋 ...
- 封装一个的toast弹出框(vue项目)
逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...
- Vue el 使用el-checkbox-group复选框进行单选框操作
el-checkbox-group这个组件与其他复选框不一样,我当初也是半天不知道怎么操作 页面使用v-model绑定 size就是等比例缩小放大,v-ror循环应该看的懂.重要的是@chage到我们 ...
- 如何洗白xi校长?(初稿)
看看咱们太子殿下,谁还敢黑全世界最好的太子殿下 我们不如来考虑一下如何给校长洗白. 第一当然是买断热搜了.买断热搜可以阻止消息进一步传播.当然这种操作学校再8月18日晚就已经做过了.8月18日该条消息 ...
- [CSP-S 2021] 回文
题目描述: 给定正整数 n 和整数序列 a1, a2,-,a2n,在这 2n 个数中,1, 2,-,n 分别各出现恰好 2 次.现在进行 2n 次操作,目标是创建一个长度同样为 2n 的序列 b 1, ...
- Python课程笔记(八)
一些简单的文件操作,学过linux的话理解感觉不会很难.课程代码 一.OS 目录方法 这个模块提供了一种方便的使用操作系统函数的方法 函数 说明 os.mkdir("path") ...
- cf16E Fish(状压DP)
题意: N只FISH.每个回合会有一只FISH吃掉另一个FISH.直到池塘里只剩一只FISH. 给出aij:第i只FISH吃掉第J只FISH的概率. 问每一只FISH是最后存活者的概率. Input ...
- Dubbo框架协议总结
Dubbo支持的各种协议及相关特性及应用场景,均可在官网文档中找到. 支持的协议有dubbo.rmi.hession.http.webservice.thrift.memcached.redis.re ...
- java+selenium+testNG+Allure报表【新增截图到报表功能】
1.pom.xml配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...
- 津门杯WriteUP
最近很浮躁,好好学习 WEB power_cut 扫目录 index.php <?php class logger{ public $logFile; public $initMsg; publ ...