牛客 位数差(二分)

通过式子转化,考虑贡献,设bit(x)为x的位数,答案为所有组合的位数-(n-i)*a[i]的位数

后一个式子可以读入处理,前一个式子先排序后用二分找到变化边界,从大往小遍历二分,答案只有位数+1或者跟原位数相符。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int a[N];
int bi[N];
int get(int x){
    int res=0;
    if(x==0)
    return 1;
    while(x){
        res++;
        x/=10;
    }
    return res;
}
int main(){
    int i;
    int n;
    cin>>n;
    ll sum=0;
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum-=(n-i)*get(a[i]);
    }
    sort(a+1,a+1+n);
    reverse(a+1,a+1+n);
    for(int i=1;i<n;i++)
    {
        int l=i+1,r=n,mid;
        while(l<r)
        {
            mid=(l+r)/2;
            if(get(a[i]+a[mid])>get(a[i])) l=mid+1;
            else r=mid;
        }
        sum+=ll((r-1-i)*(get(a[i])+1)+(n-r+1)*get(a[i]));
    }
    cout<<sum<<endl;
}
View Code

 

posted @ 2020-05-22 15:01  朝暮不思  阅读(163)  评论(0编辑  收藏  举报