Acwing第43场周赛B题(两个数列)

本文介绍了一种计算正整数数列中,给定元素和总和条件下,每个元素可能取值范围受限的无法取到的数值数量的方法。通过数学推导,给出了计算公式,并提供了C++代码实现,适用于1≤n≤2×10^5的测试数据范围。
摘要由CSDN通过智能技术生成

4315. 两个数列

题目描述

有两个正整数数列 a 1 , a 2 , … , a n a1,a2,…,an a1,a2,,an b 1 , b 2 , … , b n b1,b2,…,bn b1,b2,,bn

现在,已知的信息有:

  1. 数列 a a a 的各个元素的值。
  2. 数列 b b b 的各个元素之和 s s s
  3. 对于任意的 1 ≤ i ≤ n 1≤i≤n 1in,满足 1 ≤ b i ≤ a i 1≤b_i≤a_i 1biai 成立。

由上述信息,我们可知对于元素 b i b_i bi,其可能的取值范围为 [ 1 , a i ] [1,a_i] [1,ai],但是受到已知条件的约束,它可能无法取到其中一些数值。

我们的任务就是计算每个 b i b_i bi 在其可能的取值范围内,无法取到的数值的数量。

例如,如果 n = 2 , a = { 4 , 4 } , s = 8 n=2,a=\{4,4\},s=8 n=2a={4,4}s=8,则数列 b b b 中的每一个元素都不能小于 4 4 4(否则,另一个元素就要大于 4 4 4,这是不可能的),也就是说 b 1 b_1 b1 b 2 b_2 b2 在其可能的取值范围 [ 1 , 4 ] [1,4] [1,4] 内,均无法取到 1 , 2 , 3 1,2,3 1,2,3,无法取到的数值的数量均为 3 3 3

输入格式

第一行包含两个整数 n n n s s s

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an

输出格式

共一行, n n n 个整数,其中第 i i i 个整数表示 b i b_i bi 在其可能的取值范围内,无法取到的数值的数量。

数据范围

前三个测试点满足 1 ≤ n ≤ 2 1≤n≤2 1n2
所有测试点满足 1 ≤ n ≤ 2 × 1 0 5 , n ≤ s ≤ ∑ i = 1 n a i , 1 ≤ a i ≤ 1 0 6 1≤n≤2×10^5,n \leq s \leq \sum_{i=1}^{n} a_{i},1≤a_i≤10^6 1n2×105nsi=1nai1ai106

输入样例1:

2 8
4 4

输出样例1:

3 3

输入样例2:

1 3
5

输出样例2:

4

输入样例3:

2 3
2 3

输出样例3:

0 1

解题思路

其实就是解一个不等式,用数学推导公式~
下面我们来推导一下公式!
已知有两个正整数数列: a 1 , a 2 , … , a n a1,a2,…,an a1,a2,,an
b 1 , b 2 , … , b n b1,b2,…,bn b1,b2,,bn
b b b的各个元素之和为 S S S,即 S = b 1 + b 2 + . . . + b n S=b_1+b_2+...+b_n S=b1+b2+...+bn;
S i = b 1 + b 2 + . . . b i − 1 + b i + 1 . . . + b n S_i=b_1+b_2+...b_{i-1}+b_{i+1}...+b_n Si=b1+b2+...bi1+bi+1...+bn S u m = a 1 + a 2 + . . . + a n Sum=a_1+a_2+...+a_n Sum=a1+a2+...+an
又因为,对于任意的 1 ≤ i ≤ n 1≤i≤n 1in,满足 1 ≤ b i ≤ a i 1≤b_i≤a_i 1biai 成立;
则: n − 1 ≤ S i ≤ S u m − a i n-1≤S_i≤Sum-a_i n1SiSumai

− n + 1 ≥ − S i ≥ − S u m + a i -n+1\geq -S_i\geq -Sum+a_i n+1SiSum+ai
S − n + 1 ≥ S − S i ≥ S − S u m + a i S-n+1\geq S-S_i\geq S-Sum+a_i Sn+1SSiSSum+ai
又因为 S − S i = b i S-S_i=b_i SSi=bi,则有
S − n + 1 ≥ b i ≥ S − S u m + a i S-n+1\geq b_i\geq S-Sum+a_i Sn+1biSSum+ai

最终我们只需要取 1 ≤ b i ≤ a i 1≤b_i≤a_i 1biai集合和 S − n + 1 ≥ b i ≥ S − S u m + a i S-n+1\geq b_i\geq S-Sum+a_i Sn+1biSSum+ai集合的交集即可!~
在这里插入图片描述

又因为 n ≤ S ≤ S u m n \leq S \leq Sum nSSum
b i b_i bi的取值范围大概在 [ n − S u m + a i , S u m − n + 1 ] [n-Sum+a_i,Sum-n+1] [nSum+ai,Sumn+1]


由于测试点满足 1 ≤ n ≤ 2 × 1 0 5 , n ≤ s ≤ ∑ i = 1 n a i , 1 ≤ a i ≤ 1 0 6 1≤n≤2×10^5,n \leq s \leq \sum_{i=1}^{n} a_{i},1≤a_i≤10^6 1n2×105nsi=1nai1ai106


所以集合 S − n + 1 ≥ b i ≥ S − S u m + a i S-n+1\geq b_i\geq S-Sum+a_i Sn+1biSSum+ai的取值范围在 [ 1 , 2 × 1 0 11 ] [1,2×10^{11}] [1,2×1011]与集合 1 ≤ b i ≤ a i 1≤b_i≤a_i 1biai(取值范围大约在 [ 1 , 1 0 6 ] [1,10^6] [1,106]),所以数据保证是一定有交集的,所以情况三不存在,即集合长度 d = m i n ( b , d ) − m a x ( a , c ) + 1 d=min(b,d)-max(a,c)+1 d=min(b,d)max(a,c)+1

c++代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

int n;
LL s;
int a[N];

LL get(LL a, LL b, LL c, LL d)
{
    return min(b, d) - max(a, c) + 1;
}

int main()
{
    scanf("%d%lld", &n, &s);
    
    LL sum = 0;
    /*读入a数组,并计算a1+a2+...+an*/
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &a[i]);
        sum += a[i];
    }
    
    for (int i = 1; i <= n; i ++ )//输出答案~
        printf("%d ", a[i] - get(s - sum + a[i], s - n + 1, 1, a[i]));
        
    return 0;
}

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( n ) O(n) O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nie同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值