zoukankan      html  css  js  c++  java
  • CODEFORCEs 621E. Wet Shark and Blocks


    E. Wet Shark and Blocks
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    There are b blocks of digits. Each one consisting of the same n digits, which are given to you in the input. Wet Shark must chooseexactly one digit from each block and concatenate all of those digits together to form one large integer. For example, if he chooses digit1 from the first block and digit 2 from the second block, he gets the integer 12.

    Wet Shark then takes this number modulo x. Please, tell him how many ways he can choose one digit from each block so that he gets exactly k as the final result. As this number may be too large, print it modulo 109 + 7.

    Note, that the number of ways to choose some digit in the block is equal to the number of it's occurrences. For example, there are 3ways to choose digit 5 from block 3 5 6 7 8 9 5 1 1 1 1 5.

    Input

    The first line of the input contains four space-separated integers, nbk and x (2 ≤ n ≤ 50 000, 1 ≤ b ≤ 109, 0 ≤ k < x ≤ 100, x ≥ 2) — the number of digits in one block, the number of blocks, interesting remainder modulo x and modulo x itself.

    The next line contains n space separated integers ai (1 ≤ ai ≤ 9), that give the digits contained in each block.

    Output

    Print the number of ways to pick exactly one digit from each blocks, such that the resulting integer equals k modulo x.

    Sample test(s)
    input
    12 1 5 10
    3 5 6 7 8 9 5 1 1 1 1 5
    output
    3
    input
    3 2 1 2
    6 2 2
    output
    0
    input
    3 2 1 2
    3 1 2
    output
    6
    Note

    In the second sample possible integers are 222662 and 66. None of them gives the remainder 1 modulo 2.

    In the third sample integers 1113212331 and 33 have remainder 1 modulo 2. There is exactly one way to obtain each of these integers, so the total answer is 6.

     题意:

    给你n个数,给你b个格子,然后每个格子里有n种选择,也就是前面给的n个数,每个格子只能选择1个数。问这格子组成的数字有多种不同的组合是%x=k的。

    思路:首先要用dp来解决,dp[i][j]表示前i个格子组成的数%x取余位j的个数,那么可以得到递推方程式dp[i][j]=(dp[i][j]+dp[i-1][k]*ans[z]);(这里的k和上面的不同)

    其中(10*k+z)%x=j;由于i的范围很大,所以不可以循环来解决。可以用矩阵快速幂来优化。

    mm[i][j]是系数矩阵,为啥可以用矩阵快速幂,因为每一层的1-9的个数及种类是不变的,而且前面的数*10+本层的数%x是不变的。

     所以dp[i]=dp[0]*(mm[i][j])^b; mm[i][j]表示由(i*10+k)%x=j的种数,(k>=0&&k<=9)。(这里的k和上面的不同)

     mm[i][j]=(mm[i][j]+cnt[k]);(i*10+k)%x=j;系数矩阵可这样求得。

    然后最后答案就是nn[0][k]    (nn[i][j]=(mm[i][j])^b); 因为初始只有dp[0][0]=1; 

      

      1 #include<stdio.h>

      2 #include<algorithm>

      3 #include<iostream>
      4 #include<string.h>
      5 #include<stdlib.h>
      6 #include<queue>
      7 #include<stack>
      8 #include<cstdio>
      9 #define sc(x) scanf("%I64d",&x)
     10 #define pr(x) printf("%I64d",x)
     11 #define prr(x) printf("%I64d ",x);
     12 #define prrr(x) printf("%I64d ",x);
     13 void quick(long long  k,long long n);
     14 void juz(int k);
     15 void chu();
     16 const long long E=1e9+7;
     17 typedef long long ll;
     18 ll aa[20];
     19 ll ju[200][200];
     20 ll bb[200];
     21 ll vv[200];
     22 ll we[200];
     23 ll mm[200][200];
     24 ll rm[200][200];
     25 using namespace std;
     26 int main(void)
     27 {
     28     ll i,j,k,p,q,n,m;
     29     while(scanf("%I64d %I64d %I64d %I64d",&k,&p,&q,&n)!=EOF)
     30     {
     31         memset(aa,0,sizeof(aa));
     32         memset(ju,0,sizeof(ju));
     33         memset(we,0,sizeof(we));
     34         memset(bb,0,sizeof(bb));
     35         memset(vv,0,sizeof(vv));
     36         for(i=0; i<k; i++)
     37         {
     38             scanf("%I64d",&m);
     39             aa[m]++;
     40         }
     41         for(i=0; i<10; i++)
     42         {
     43             bb[i%n]=(aa[i]+bb[i%n])%E;
     44         }
     45         memset(rm,0,sizeof(rm));
     46         for(i=0;i<10;i++)
     47         {
     48             for(j=0;j<10;j++)
     49             {
     50                 if(i==j)
     51                 {if(bb[i]!=0)
     52                   rm[i][j]=1;
     53                   vv[i]=1;
     54                 }
     55             }
     56         }
     57         if(p==1)
     58         {
     59             prr(bb[q]);
     60         }
     61         else
     62         {
     63             juz(n);
     64             quick(p,n);
     65 
     66             we[0]=1;
     67             prr(mm[0][q]);
     68         }
     69     }
     70     return 0;
     71 
     72 }
     73 
     74 void juz(int k)
     75 {
     76     int i,j,p,q;
     77     ll dd[200];
     78     memset(dd,0,sizeof(dd));
     79     dd[0]=1;
     80     memset(ju,0,sizeof(ju));
     81     for(i=0; i<=k-1; i++)
     82     for(j=0; j<=k-1; j++)
     83     for(p=0; p<=k-1; p++)
     84     if((10*j+p)%k==i)
     85     {ju[j][i]=(ju[j][i]+bb[p])%E;
     86     }
     87 }
     88 
     89 void quick(ll k,ll n)
     90 {
     91    int i,j,p,q;
     92    ll nn[200][200];
     93    memset(mm,0,sizeof(mm));
     94 
     95    chu();
     96    while(k)
     97    {memset(nn,0,sizeof(nn));
     98     if(k&1)
     99     {
    100     for(i=0;i<=n-1;i++)
    101     for(j=0;j<=n-1;j++)
    102     for(int s=0;s<=n-1;s++)
    103     nn[i][j]=(((ju[i][s]%E)*(mm[s][j]%E))%E+nn[i][j])%E;
    104     for(i=0;i<n;i++)
    105     for(j=0;j<n;j++)
    106     mm[i][j]=nn[i][j];
    107     }memset(nn,0,sizeof(nn));
    108     for(i=0;i<=n-1;i++)
    109     for(j=0;j<=n-1;j++)
    110     for(int s=0;s<=n-1;s++)
    111     nn[i][j]=(((ju[i][s]%E)*(ju[s][j]%E))%E+nn[i][j])%E;
    112     for(i=0;i<n;i++)
    113     for(j=0;j<n;j++)
    114     ju[i][j]=nn[i][j];
    115     k/=2;
    116    }
    117 }
    118 void chu()
    119 {int i,j,k,p,q;
    120 for(i=0;i<=200;i++)
    121 for(j=0;j<=200;j++)
    122     if(i==j)
    123     mm[i][j]=1;
    124 }
    油!油!you@
  • 相关阅读:
    *** mixed implicit and normal rules: deprecated syntax
    cold boot and warm boot.
    git打补丁命令
    LSB和MSB
    __attribute__((weak)) ------ 关于弱符号的用法
    键盘和鼠标无法热插拔问题
    yocto编译加速及单独编译内核与uboot
    V4L2学习教程
    linux错误码
    linux内核面试常见试题
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5179550.html
Copyright © 2011-2022 走看看