1 条题解

  • 0
    @ 2025-8-24 23:05:12

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Xuan_qwq
    QQ:3054662060 | 毫无实力

    搬运于2025-08-24 23:05:12,当前版本为作者最后更新于2024-10-17 16:31:35,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我们知道,一个数 xxkk 位,等价于 10k1x<10k10^{k-1} \leq x < 10^{k}

    那么,ai+bja_i+b_jkk 位等价于 10k1ai+bj<10k10^{k-1} \leq a_i+b_j < 10^{k},即 10k1aibj<10kai10^{k-1}-a_i \leq b_j < 10^{k}-a_i

    所以我们考虑枚举每一个 aia_i,对所有 1k101\le k \le 10 计算 BB 中满足 10k1aibj<10kai10^{k-1}-a_i \leq b_j < 10^{k}-a_ibib_i 数量 si,ks_{i,k},这可以很容易地用 lower_bound 函数求出。

    最终答案为:

    ans=i=1nk=110si,k×kans=\sum_{i=1}^n \sum_{k=1}^{10}s_{i,k}\times k

    至于为什么只需要计算 1k101\le k \le 10 即可,是因为 ai+bja_i+b_j 的最大值不超过 999999999+999999999=1999999998<1010999999999+999999999=1999999998 < 10^{10},所以一个和最多只有 1010 位。

    ACcode

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int a[150005],b[150005],n,ans;
    signed main(){
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin>>n;
    	for(int i=0;i<n;i++)cin>>a[i];
    	for(int i=0;i<n;i++)cin>>b[i];
    	sort(b,b+n);
    	for(int i=0;i<n;i++){
    		int lim=1;//lim为10的k-1次方
    		for(int k=1;k<=10;k++){
    			if(lim*10<a[i]){//小优化,如果a[i]>10^k,那就不用算
    				lim*=10;
    				continue;
    			}
    			int ps1=lower_bound(b,b+n,lim-a[i])-b;
    			int ps2=lower_bound(b,b+n,lim*10-a[i])-b;
    			ans+=k*(ps2-ps1);//计算 k*s[i][k]
    			lim*=10;
    			if(b[n-1]+a[i]<lim)break;//和上面差不多的小优化
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
    • 1

    [JOIG 2024] たくさんの数字 / Many Digits

    信息

    ID
    10883
    时间
    2000ms
    内存
    1024MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者