Official

G - Another Sigma Problem Editorial 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;
}

posted:
last update: