题解:P15729 [JAG 2024 Summer Camp #2] Add Add Add
题目传送门
解题思路
本题可以把 \(k\) 分两种情况讨论,数学推导得出:
- 当 \(k = 2, 3, \ldots, N + 1\) 时,\(\sum_{i+j \leq k} (A_i + B_j) = \sum_{i+j \leq (k - 1)} (A_i + B_j) + \sum_{i = 1}^{k - 1} {A[i]} + \sum_{i = 1}^{k - 1} {B[i]}\) 。
- 当 \(k = N + 2, N + 3 \ldots, 2N\) 时,\(\sum_{i+j \leq k} (A_i + B_j) = \sum_{i+j \leq (k - 1)} (A_i + B_j) + \sum_{i = k - N}^{N} {A[i]} + \sum_{i = k - N}^{k - 1} {B[i]}\)。
那么需要求和时,可以想到使用前缀和快速访问一段区间的和。
注意
本题数据范围较大,需使用long long。
AC Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[200010],b[200010],s[400010];
c1[200010],c2[200010],d1[200010],d2[200010]; //定义前缀和数组
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=1;i<=n;i++){ //求左前缀和
c1[i]=c1[i-1]+a[i];
c2[i]=c2[i-1]+b[i];
}
for(int i=n;i>=1;i--){ //求右前缀和
d1[i]=d1[i+1]+a[i];
d2[i]=d2[i+1]+b[i];
}
for(int i=2;i<=n+1;i++){ //求情况一的答案
s[i]=s[i-1]+c1[i-1]+c2[i-1];
cout<<s[i]<<endl;
}
for(int i=n+2;i<=2*n;i++){ //求情况二的答案
s[i]=s[i-1]+d1[i-n]+d2[i-n];
cout<<s[i]<<endl;
}
return 0;
}

浙公网安备 33010602011771号