zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    矩阵乘法
    年关了,抛一个模拟ip刷票的php程序
    mysql处理大数据合并的另一种方法
    php之aop实践
    轻量级php框架phpk v1.0发布
    eclipse
    super关键字的使用
    方法的重写
    方法的重载
    java 构造器 (构造方法)
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007211.html
Copyright © 2011-2022 走看看