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 22, 26, 62 and 66. None of them gives the remainder 1 modulo 2.

In the third sample integers 11, 13, 21, 23, 31 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\n",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 }

CODEFORCEs 621E. Wet Shark and Blocks的更多相关文章

  1. 【矩阵乘法优化dp】[Codeforces 621E] Wet Shark and Blocks

    http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test 2 seconds ...

  2. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  3. cf 621E. Wet Shark and Blocks

    神奇,矩阵乘法23333333333333333 递推式是很简单的(连我这种不会DP的人都写出来了.) 需要求出的是转移矩阵(还是叫系数矩阵的),也是最这个东西用快速幂. 这个东西的i,j大概就表示从 ...

  4. Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks dp+矩阵加速

    题目链接: http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test2 se ...

  5. 【38.24%】【codeforces 621E】 Wet Shark and Blocks

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. Codeforces 612B. Wet Shark and Bishops 模拟

    B. Wet Shark and Bishops time limit per test: 2 seconds memory limit per test: 256 megabytes input: ...

  7. Codeforces Round #341 (Div. 2) E - Wet Shark and Blocks

    题目大意:有m (m<=1e9) 个相同的块,每个块里边有n个数,每个数的范围是1-9,从每个块里边取出来一个数组成一个数,让你求组成的方案中 被x取模后,值为k的方案数.(1<=k< ...

  8. [cf621E]Wet Shark and Blocks

    Description 给定$n$个数和$b$个盒子,放一些数到盒子中,使得盒子不为空.每个盒子中的数是一样的,一个数可以被放到多个盒子中. 从每个盒子中取一个数,组成一个$b$位数,如果这个数$mo ...

  9. CodeForces 621C Wet Shark and Flowers

    方法可以转化一下,先计算每一个鲨鱼在自己范围内的数能被所给素数整除的个数有几个,从而得到能被整除的概率,设为f1,不能被整除的概率设为f2. 然后计算每相邻两只鲨鱼能获得钱的期望概率,f=w[id1] ...

随机推荐

  1. C# / VB.NET 在Word中嵌入多媒体(视频、音频)文件

    Word中可将Office(Word/Excel/PowerPoint).PDF.txt等文件作为OLE对象插入到文档中,双击该对象可直接访问或编辑该文件,除了以上常见的文件格式对象,也可以插入多媒体 ...

  2. SQLite is 35% Faster Than The Filesystem

    比方说你要在C++/PHP里实现一个函数Image get_image(string id),不同的图片有1万张(用户头像),你可以把它们存在一个目录/文件夹里,然后fopen()再fread. 你也 ...

  3. 【原创】Altium生成Gerber时跳出The Film is too small for this PCB的解决办法

    在用altium Designer画板子的时候,要生成gerber文件的时候,会出错,出现这样的提示框:"The Film is too small for this PCB" 原 ...

  4. window ntp服务

    一.确定服务端和客户端处于同一网段,能相互 Ping 通. 二.服务器端(Server)配置 1.选择一台服务器(Windows 系统)作为时间同步服务器: 2.Win + R (运行 cmd 命令行 ...

  5. navigationItem的leftBarButtonItem和rightBarButtonItem隐藏

    - (void)showEdit { if (不符合显示条件) { self.navigationItem.rightBarButtonItem.customView.hidden = YES; // ...

  6. mysql锁相关讲解及其应用

    一.mysql的锁类型 了解Mysql的表级锁 了解Mysql的行级锁 (1) 共享/排它锁(Shared and Exclusive Locks) 共享锁和排他锁是InnoDB引擎实现的标准行级别锁 ...

  7. 理解JMX之介绍和简单使用

    JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,然后使用JConsole或Visual VM进行预览.下图是使用Jconsle通过JMX查看Java程序的运 ...

  8. 图书管理系统总结——数据库操纵(二):DML语句

    这里以最基本的DML语句作为例子,其他各种复杂的DML语句可以根据这些基本JDBC语句得到. 一.查询表格 这里以两张表关联查询为例,采用动态方式,根据输入的条件在WHERE语句后面接上相应的各种条件 ...

  9. 使用cookie记录用户上次访问网页的时间,并返回到页面

    package com.hopetesting.cookie;import javax.servlet.ServletException;import javax.servlet.annotation ...

  10. Django REST framework完全入门

    Django REST framework 一个强大灵活的Django工具包,提供了便捷的 REST API 开发框架 我们用传统的django也可以实现REST风格的api,但是顶不住Django ...