CF1416E-Split【dp,set】

1|0正题

题目链接:https://www.luogu.com.cn/problem/CF1416E


1|1题目大意

给出n个正整数的一个序列ai,你要把ai拆成两个正整数的和b2i,b2i+1,要求使得b的相同连续段最少。

1n5×105,1ai109


1|2解题思路

考虑求最大的相邻相同数目,先考虑暴力的dp,设fi,j表示分解完aib2i+1=j时的方案,那么有转移方程

fi,j=max{fi1,k+[k=aij]}+[2j=ai]

而且不难发现对于一个i来说它的所有fi,j在加上[2j=ai]之前差距不会超过1,而且我们显然只有可能从最大值转移。

对于2j=ai的情况很难处理,我们可以先考虑都是奇数的情况。

首先开始都有f1,j=0,可以记为区间[1,a11],然后到第二个对于一个最大的j,我们可以转移到a2j(如果合法)。同样的我们可以翻转之后得到一个新的最大区间[l,r],当某次之后这个区间空了那么因为上面提到的fi,j的差距不会超过1,所以最大值不变然后区间变回[1,ai1]

之后考虑ai有偶数的情况怎么处理,此时会出现的问题就是:如果ai2加之前是最大值,那么加上之后就变为了唯一的最大值,这个很好处理,而如果之前不是最大值,那么加了之后就变为了最大值。

这个时候有可能会在区间之外出现一些单点的最大值,我们可以用set来储存这些位置,至于翻转之后所有的位置x都会变为aix,那么可以储存一个x表示实际上这个位置的值为x×f+buf的情况,这样我们就可以快速的翻转然后把不合法的值去掉就好了。

时间复杂度:O(nlogn)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<set> #define ll long long using namespace std; const ll N=5e5+10; ll T,n,ans,l,r,flag,f,buf,a[N]; set<ll> s; void solve(ll lim){ flag=1; if(l<=r){ if(lim<=l)l=1,r=0; else l=lim-l,r=lim-min(r,lim-1),swap(l,r),flag=0; } f=f*-1;buf=lim-buf; while(!s.empty()){ ll w=(*s.begin())*f+buf; if(w<1||w>=lim)s.erase(s.begin()); else break; } while(!s.empty()){ ll w=(*(--s.end()))*f+buf; if(w<1||w>=lim)s.erase(--s.end()); else break; } return; } signed main() { scanf("%lld",&T); while(T--){ s.clear();f=ans=1;buf=flag=0; scanf("%lld",&n); for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); if(a[1]&1)l=1,r=a[1]-1,ans++; else l=r=a[1]/2; for(ll i=2;i<=n;i++){ // if(s.size())printf("%d\n",*s.begin()); if(a[i]&1){ solve(a[i]);ans++; if(s.empty()&&flag)l=1,r=a[i]-1,ans++; } else{ if(s.find((a[i]/2-buf)*f)!=s.end()||a[i]/2>=l&&a[i]/2<=r) s.clear(),l=r=a[i]/2; else solve(a[i]),s.insert((a[i]/2-buf)*f),ans++; } } printf("%lld\n",ans); } return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15557928.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(63)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示