Wannafly挑战赛3-C.位数差(思维)

给一个数组{a},定义 h(a,b) 为在十进制下 a + b 与 a 的位数差,求 1i<jnh(aiaj) ,0的位数为1。 1n1e50ai1e8

思路:
  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;
}

猜你喜欢

转载自blog.csdn.net/qq_29556211/article/details/78550304