zoukankan      html  css  js  c++  java
  • CF1029D Solution

    题目链接

    题解

    如果(k)整除两个接起来的数(a_i,a_j),它们一定满足(k|(a_icdot10^{dig_j}+a_j)),其中(dig_j)(a_j)的数位。由于求余运算的可加、乘性,(a_i,a_j)需要满足(k|[(a_i\%k)cdot(10^{dig_j}\%k)+a_j\%k]),也就是只需知道(a_i)(10^{dig_j})(a_j)(k)的余数即可。可以发现(dig_j)是不确定的,因此需要将(a)数组依照数位划分,重新存入(mod)数组中。此外,枚举(a_j)的时间复杂度为(O(n^2)),因此需要将(mod)数组排序后二分查找,时间复杂度(O(nlogn))。还有,二分查找的结果可能会包含(a_i)本身,因此如果数位相同且(a_i)合法,(ans)需要(-1)

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e5+10;
    int a[N],mod[15][N],len[15],dig[N],pw[15],k;
    //mod[i][j]:第j个数位为i的数,len[i]:数位为i数的个数,dig[i]:a[i]的数位,pw[i]:10^i模k的余数
    void init()
    {
    	pw[0]=1;
    	for(int i=1;i<=10;i++) pw[i]=pw[i-1]*10%k;
    }//预处理pw数组
    signed main()
    {
    	int n,maxd=0,ans=0; 
    	scanf("%lld%lld",&n,&k);
    	init();
    	for(int i=1;i<=n;i++) 
    	{
    		scanf("%lld",&a[i]);
    		int qwq=a[i];
    		while(qwq) {qwq/=10; dig[i]++;}
    		maxd=max(maxd,dig[i]);
    		mod[dig[i]][++len[dig[i]]]=a[i]%k;
    	}
    	for(int i=1;i<=maxd;i++) sort(mod[i]+1,mod[i]+len[i]+1);
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=maxd;j++)
    		{
    			int qaq=(k-a[i]*pw[j]%k)%k;
    			int r=upper_bound(mod[j]+1,mod[j]+len[j]+1,qaq)-mod[j];
    			int l=lower_bound(mod[j]+1,mod[j]+len[j]+1,qaq)-mod[j];
    			ans+=r-l;
    			if(dig[i]==j && (a[i]*pw[j]+a[i])%k==0) ans--;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    单元测试、集成测试、系统测试
    函数
    python中的math函数
    字符串和数据类型转换
    range()函数
    input()函数
    Linux如何通过命令查看日志文件的某几行(中间极几行或最后几行)
    【转】接口测试面试题
    【转】用Fiddler做抓包分析详解
    为什么要使用fiddler抓包?抓包用来干什么?
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14257497.html
Copyright © 2011-2022 走看看