ARC158C 题解

  • ~1.70K 字
  1. 1. 题意简述
  2. 2. 分析
  3. 3. 代码

“かけがえのない日々を ここで 積みかさねて ひとつひとつ いまさらわかった”—— 《想いよひとつになれ》

题意简述

f(x)f(x)xx 的数字和。例如 f(158)=1+5+8=14f(158)=1+5+8=14

给定一个长度为 NN 的正整数序列 AA,求 i=1Nj=1Nf(Ai+Aj)\sum_{i=1}^{N}\sum_{j=1}^{N}f(A_i+A_j)

分析

g(a,b)g(a,b)a+ba+b 进位的次数,则 f(a+b)=f(a)+f(b)9×g(a,b)f(a+b)=f(a)+f(b)-9 \times g(a,b),其中 i=1Nj=1Nf(Ai)+f(Aj)=2n×i=1Nf(Ai)\sum_{i=1}^{N}\sum_{j=1}^{N}f(A_i)+f(A_j)=2 n \times \sum_{i=1}^{N} f(A_i)

考虑如何计算 i=1Nj=1Ng(Ai,Aj)\sum_{i=1}^{N}\sum_{j=1}^{N}g(A_i,A_j)。对于两个数 x,yx,y,如果 x+yx+y 在第 dd 位上有进位,当且仅当 xmod10d+ymod10d10d+1x \bmod 10^d+y \bmod 10^d \geq 10^{d+1}。将所有 Aimod10dA_i \bmod 10^d 排序,枚举 ddAjA_j 去二分 Aimod10dA_i \bmod 10^d 中大于 10d+1Ajmod10d10^{d+1}-A_j \bmod 10^d 的值的个数即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const int N = 200005,M = 17;
int a[M][N];
int n;

signed main(){
cin >> n;
int ans = 0;
for(int k=1;k<=n;k++){
int c;
cin >> c;
int d = 10;
for(int j=1;j<M;j++){
a[j][k] = c%d;
d *= 10;
}
while(c){
ans += c%10;
c /= 10;
}
}
ans *= 2*n;
for(int k=1;k<M;k++)
sort(a[k]+1,a[k]+1+n);
int d = 10;
int sum = 0;
for(int k=1;k<M;k++){
for(int j=1;j<=n;j++){
int w = a[k]+n+1-lower_bound(a[k]+1,a[k]+1+n,d-a[k][j]);
sum += w;
}
d *= 10;
}
cout << ans-sum*9;
return 0;
}