High Load Database Gym - 102411H (前缀和+二分查找)
题目出处
High Load Database Gym - 102411H
ICPC 2019-2020 North-Western Russia Regional Contest
题意
给长度为n的整数序列。
询问q次, 每次给定一个整数t, 你要把给定的序列尽可能少的划分, 要求每部分的区间和不大于t.
最终输出最少划分区间的数目。
思路
这道题是很明显的前缀和+二分的题目。
因为涉及到区间和, 所以不难想到利用前缀和进行O(1)的化简。
而二分的地方在于:
-
这个区间要么是不可能的
即区间中的最大元素比给定的t大. -
除此之外的情况就是可以二分的了;
因为这个区间一定被划分成1-n份, n份一定是可行的. 在对于区间[l, r]划分时, 我们希望尽可能的靠右去划分(因为要保证分割尽可能少), 所以直接套二分模板, 每次改变被划分的区间即可.
代码
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define int long long const int N=2e6+10; int a[N]; int ans[N]; int prefix[N]; int n,m; int solve(int x) { if(ans[x]) return ans[x]; int step=0; int last=1; while(last<=n) { int pos=upper_bound(prefix+1,prefix+n+1,x+prefix[last-1])-prefix;//找出第一个大于等于last的数 //cout<<pos<<"-->"<<endl; last=pos; step++; } return ans[x]=step; } signed main() { scanf("%lld",&n); int maxx=-1; for(int i=1;i<=n;i++) scanf("%lld",&a[i]),maxx=max(maxx,a[i]); for(int i=1;i<=n;i++) prefix[i]=prefix[i-1]+a[i]; scanf("%lld",&m); while(m--) { int x; scanf("%lld",&x); if(x<maxx) printf("Impossible\n"); else printf("%lld\n",solve(x)); } return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16814689.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步