两个数列
两个数列
有两个正整数数列 和 。
现在,已知的信息有:
- 数列 的各个元素的值。
- 数列 的各个元素之和 。
- 对于任意的 ,满足 成立。
利用给出的信息,我们可以对数列 中各个元素的值进行推断。
由上述信息,我们可知对于元素 ,其可能的取值范围为 ,但是受到已知条件的约束,它可能无法取到其中一些数值。
我们的任务就是计算每个 在其可能的取值范围内,无法取到的数值的数量。
例如,如果 ,,,则数列 中的每一个元素都不能小于 (否则,另一个元素就要大于 ,这是不可能的),也就是说 和 在其可能的取值范围 内,均无法取到 ,无法取到的数值的数量均为 。
输入格式
第一行包含两个整数 和 。
第二行包含 个整数 。
输出格式
共一行, 个整数,其中第 个整数表示 在其可能的取值范围内,无法取到的数值的数量。
数据范围
前三个测试点满足 。
所有测试点满足 ,,。
输入样例1:
2 8 4 4
输出样例1:
3 3
输入样例2:
1 3 5
输出样例2:
4
输入样例3:
2 3 2 3
输出样例3:
0 1
解题思路
每个是独立求解的,不需要考虑与其他的相关性。
首先要满足。
假设所有的总和为,用来表示除了其他的的和,即。同理,用来表示除了其他的的和。
那么就有,。
我们要求的取值范围,那么先求的取值范围。
由于每个都有,因此有,,因此有。
即。同时要满足,因此最后我们求这两个不等式的交集就可以了。
因为题目的数据范围保证每个都可以取到值,因此这两个不等式一定会有交集。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef long long LL; 6 7 const int N = 2e5 + 10; 8 9 LL a[N]; 10 11 int get(LL a, LL b, LL c, LL d) { 12 return min(b, d) - max(a, c) + 1; // 两个区间的交集为左端点的最大值与右端点的最小值 13 } 14 15 int main() { 16 LL n, sb; 17 scanf("%lld %lld", &n, &sb); 18 19 LL sa = 0; 20 for (int i = 0; i < n; i++) { 21 scanf("%lld", a + i); 22 sa += a[i]; 23 } 24 25 for (int i = 0; i < n; i++) { 26 printf("%d ", a[i] - get(1, a[i], sb - (sa - a[i]), sb - (n - 1))); 27 } 28 29 return 0; 30 }
参考资料
AcWing 4315. 两个数列(AcWing杯 - 周赛):https://www.acwing.com/video/3740/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16029362.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探