P7294 题解
今天模拟赛 T3 出了这道题,结果剩下时间太短正解没想完
题意简述
给出一个
再来
题目分析
由于是模拟赛题,我就按赛场上的思路写,因此从部分分开始。
简单的 DP,不用多说。预处理
考虑一下这个性质的作用。其实就是说,在
那么就好处理了。我们只需要依据
、
其实受到上一部分的启发剩下的两个范围都可以做了。
注意到上一部分中的最优的
时间复杂度
代码实现
#include<bits/stdc++.h> using namespace std; int n,m,q,a[200010],c[200010],stk[200010],top,ID;//stk[]:栈,top:栈顶,a[]:决策计算出的最优 i 位置,方便二分 long long sum[200010],ans[200010];//sum[]:代价前缀和,ans[]:询问答案 vector<pair<int,int> >Q[200010]; int P(int i,int j) { return min(n,max(int(0.5*(double)(c[j]-c[i])/(j-i)+0.5),1)); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d",&c[i]); scanf("%d",&q); for(int x,y,i=1;i<=q;i++) scanf("%d%d",&x,&y),Q[y].push_back({x,i});//把询问按 y 分类,离线下来 for(auto i:Q[1]) ans[i.second]=1ll*c[1]*(i.first-1);//特判 y=1 top=stk[1]=a[1]=1;//最初决策是 y=1 for(int i=2;i<=m;i++) { while(top>1&&a[top]>=P(stk[top],i)) top--;//弹掉不合法的决策 int x=P(stk[top],i); sum[top+1]=sum[top]+1ll*(x-a[top])*c[stk[top]]+1ll*(i-stk[top])*x*x;//维护代价的前缀和 stk[++top]=i,a[top]=x; for(auto t:Q[i]) { ID=upper_bound(a+1,a+top+1,t.first)-a-1;//二分找到对应决策位置 ans[t.second]=sum[ID]+1ll*(t.first-a[ID])*c[stk[ID]]+1ll*(i-stk[ID])*t.first*t.first;//保存答案 } } for(int i=1;i<=q;i++) printf("%lld\n",ans[i]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!