给一个数组{a},定义
h(a,b) 为在十进制下 a + b 与 a 的位数差,求∑1≤i<j≤nh(ai,aj) ,0的位数为1。1≤n≤1e5,0≤ai≤1e8
思路:
trick点是我有点没想明白两个1e8相加还能到1e9?。- - 居然判断到了九位的时候。
然后考虑到求h(a,b)的时候可以单独求a+b的位数和b的位数,然后所有的b的位数的贡献可以在一开始的时候维护出来。那么a+b的 位数的和 ,就是所有数对的加和的位数的和,那么就和顺序无关,就能从无序变成有序,排序以后,枚举每个位数,二分一下数量即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
long long mi[maxn];
int bit(int num)
{
if(num == 0) return 1;
int ret = 0;
while(num) num /= 10, ret++;
return ret;
}
int main()
{
mi[0] = 0, mi[1] = 1;
for(int i = 2; i <= 10; i++) mi[i] = mi[i -1] * 10;//
int n;
scanf("%d", &n);
long long ans = 0;
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
ans -= 1LL * bit(a[i]) * (n - i - 1);
}
sort(a, a + n);
for(int i = 0; i < n; i++)
{
for(int j = 0; j <= 9; j++)
{
long long num = lower_bound(a + i + 1, a + n, mi[j + 1] - a[i]) - lower_bound(a + i + 1, a + n, mi[j] - a[i]);
ans += 1LL * (j == 0 ? 1 : j) * num;
}
}
printf("%lld\n", ans);
return 0;
}