G - Another Sigma Problem 解説 by en_translator
We reinterpret \(f(x,y)\) in a more useful form: \(f(x,y) = 10^{\mathrm{len}(y)} x + y\), where \(\mathrm{len}(y)\) is the length of \(y\) interpreted as a string.
For each \(i\), let us find the contributions of \(A_i\) in the form of \(f(*,A_i)\) and of \(f(A_i, *)\).
The former is easy; \(f(*,A_i)\) has the term \(A_i\) itself, so the contribution to the answer is \((i-1)A_i\).
We consider the latter. The contribution is \(\sum_{k=1}^{10} d_k 10^{k} A_i\), where \(d_k\) is the number of \(j\) such that \(i < j\) and \(\mathrm{len}(A_j) = k\).
\(d_k\) can be updated in a constant time for each \(i\) (see also the sample code), so the latter contribution can be computed in \(\mathrm{O}(\log M)\) for each \(i\), where \(M\) is the maximum value in \(A\).
Therefore, the answer has been found in a total of \(\mathrm{O}(N\log M)\) time.
Sample code (C++):
#include <bits/stdc++.h>
#include "atcoder/modint"
using namespace std;
using ll = long long;
using mint = atcoder::modint998244353;
int main() {
int n;
cin >> n;
vector<int> a(n);
for(auto &v : a) cin >> v;
vector<int> d(11);
for(int i = 0; i < n; i++) {
d[to_string(a[i]).size()]++;
}
mint res = 0;
vector<mint> p10(11, 1);
for(int i = 1; i <= 10; i++) p10[i] = p10[i - 1] * 10;
for(int i = 0; i < n; i++) {
res += mint(a[i]) * i;
d[to_string(a[i]).size()]--;
for(int j = 1; j <= 10; j++) {
res += p10[j] * a[i] * d[j];
}
}
cout << res.val() << endl;
}
投稿日時:
最終更新: