• Codeforces 1029D(数论+思维)


    传送门

    题面:

    D. Concatenated Multiples

    time limit per test

    2 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    You are given an array aa, consisting of nn positive integers.

    Let's call a concatenation of numbers xx and yy the number that is obtained by writing down numbers xx and yy one right after another without changing the order. For example, a concatenation of numbers 1212 and 34563456 is a number 123456123456.

    Count the number of ordered pairs of positions (i,j)(i,j) (i≠ji≠j) in array aa such that the concatenation of aiai and ajaj is divisible by kk.

    Input

    The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, 2≤k≤1092≤k≤109).

    The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109).

    Output

    Print a single integer — the number of ordered pairs of positions (i,j)(i,j) (i≠ji≠j) in array aa such that the concatenation of aiai and ajaj is divisible by kk.

    Examples

    input

    Copy

    6 11
    45 1 10 12 11 7
    

    output

    Copy

    7
    

    input

    Copy

    4 2
    2 78 4 10
    

    output

    Copy

    12
    

    input

    Copy

    5 2
    3 7 19 3 3
    

    output

    Copy

    0
    

    Note

    In the first example pairs (1,2)(1,2), (1,3)(1,3), (2,3)(2,3), (3,1)(3,1), (3,4)(3,4), (4,2)(4,2), (4,3)(4,3) suffice. They produce numbers 451451, 45104510, 110110, 10451045, 10121012, 121121, 12101210, respectively, each of them is divisible by 1111.

    In the second example all n(n−1)n(n−1) pairs suffice.

    In the third example no pair is sufficient.

    题意:

        给你n个数,每个数可以两两拼接成一个新的数。问通过这样拼接而构成的数中能够成为被k乘除的个数。

    题目分析:

        这道题的做法相当的巧妙!(完美融入了数论的知识)(膜出题人的大脑洞)。

        首先,直接暴力做铁定超时,因此我们需要做一些算法优化。

        首先,对于两个数x,y。倘若让他们拼接成一个新的数S,我们设y的长度为len,则有:

        而因为要判断S是否整除k,则将S%k,则有:(x*pow(10,len)%k+y%k)%k=0

        而根据取模的性质,我们可以继续得到:

        ( x*pow( 10,len )%k+y%k )%k=k%k 

        x*pow(10,len)%k=( k-y%k )%k

        而在这个式子中,对于左式,我们可以把每一个左式都预处理出来,存进桶里。

        之后我们只需要枚举一遍a[i],计算 ( k - y%k )%k 。如果两个结果相等,那么就加在res。

        最后我们还需要减去a[i]和a[i]自己配对的情况即为答案。

    代码:

    #include <bits/stdc++.h>
    #define maxn 200005
    using namespace std;
    typedef long long ll;
    int a[maxn];
    map<int,ll>mp[20];
    int main()
    {
        int n,k;
        cin>>n>>k;
        for(int i=1;i<=n;i++){//预处理出来每一个(x*pow(10,len)%k)
            scanf("%I64d",&a[i]);
            ll x=a[i];
            for(int j=1;j<=10;j++){
                x=x*10%k;
                mp[j][x]++;
            }
        }
        ll res=0;
        for(int i=1;i<=n;i++){
            int len=log10(a[i])+1;//获取10进制的位数
            res+=mp[len][(k-a[i]%k)%k];//获取答案
            ll x=1;
            for(int i=1;i<=len;i++){
                x=x*10%k;
            }
            if((a[i]*x%k+a[i]%k)%k==0) res--;//排除自己跟自己配对的情况
        }
        cout<<res<<endl;
    }
    
  • 相关阅读:
    201871010116-祁英红 实验三 软件工程结对项目
    201871010116-祁英红 实验二 软件工程个人项目
    201871010116-祁英红 实验一 软件工程准备—初识软件工程
    201871010116-祁英红《面向对象程序设计(java)》课程学习总结
    201871010116-祁英红《面向对象程序设计(java)》第十七周学习总结
    201871010116-祁英红《面向对象程序设计(java)》第十六周学习总结
    201871010116-祁英红《面向对象程序设计(java)》第十五周学习总结
    201871010116-祁英红《面向对象程序设计(java)》第十四周学习总结
    201871010116-祁英红《面向对象程序设计(java)》第十三周学习总结
    201871010117-石欣钰 upower 实验四 团队作业1:软件研发团队组建
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007211.html
Copyright © 2020-2023  润新知