H - 桁差の和/Digit Diff Sum 解説
by
mechanicalpenciI
\(0\leq k\leq 9\) について、\(1\leq i\leq D\) であって、 \(A_i=k\) をみたすような \(i\) の個数を \(X_k\) とします。
ここで、 \(\displaystyle\sum_{i=1}^{D-1}\sum_{j=i+1}^D\lvert A_i-A_j\rvert=\displaystyle\sum_{1\leq i<j\leq D}\lvert A_i-A_j\rvert\) には相異なる桁の差がちょうど \(1\) 回ずつ登場します。ここで、\(0\leq k<k'\leq 9\) について、\(1\leq i<j\leq D\) であって、順序のついていない組として\(\{A_i,A_j\}=\{k,k'\}\) であるようなものはちょうど \(X_k\cdot X_{k'}\) 個存在し、\(A_i=A_j\) であるような組については
(\(\lvert A_i-A_j\rvert=0\)より)総和を計算する際に無視できる事から、
\[ \displaystyle\sum_{i=1}^{D-1}\sum_{j=i+1}^D\lvert A_i-A_j\rvert =\displaystyle\sum_{k=0}^{8}\sum_{k'=k+1}^9X_k\cdot X_{k'}\cdot \lvert k-k'\rvert \]
が成り立ちます。\(X_k\) \((0\leq k\leq 9)\) は \(O(D)\) で計算でき、その値を元に求めたい値は上式より \(O(1)\) で求める事ができるため、よってこの問題を解く事ができました。
c++による実装例:
#include <bits/stdc++.h>
using namespace std;
int main() {
int d;
string n;
long long c[10]={};
long long ans=0;
cin >> d;
cin >> n;
for (int i=0;i<d;i++)c[n[i] - '0']++;
for (int i=0;i<9;i++)for(int j=i+1;j<=9;j++)ans+=c[i]*c[j]*(j-i);
cout << ans << endl;
return 0;
}
投稿日時:
最終更新: