公式

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;
}

投稿日時:
最終更新: