CODEFORCEs 621E. Wet Shark and Blocks
2 seconds
256 megabytes
standard input
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.
The first line of the input contains four space-separated integers, n, b, k 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.
Print the number of ways to pick exactly one digit from each blocks, such that the resulting integer equals k modulo x.
12 1 5 10
3 5 6 7 8 9 5 1 1 1 1 5
3
3 2 1 2
6 2 2
0
3 2 1 2
3 1 2
6
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的更多相关文章
- 【矩阵乘法优化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 ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- cf 621E. Wet Shark and Blocks
神奇,矩阵乘法23333333333333333 递推式是很简单的(连我这种不会DP的人都写出来了.) 需要求出的是转移矩阵(还是叫系数矩阵的),也是最这个东西用快速幂. 这个东西的i,j大概就表示从 ...
- 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 ...
- 【38.24%】【codeforces 621E】 Wet Shark and Blocks
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- Codeforces 612B. Wet Shark and Bishops 模拟
B. Wet Shark and Bishops time limit per test: 2 seconds memory limit per test: 256 megabytes input: ...
- Codeforces Round #341 (Div. 2) E - Wet Shark and Blocks
题目大意:有m (m<=1e9) 个相同的块,每个块里边有n个数,每个数的范围是1-9,从每个块里边取出来一个数组成一个数,让你求组成的方案中 被x取模后,值为k的方案数.(1<=k< ...
- [cf621E]Wet Shark and Blocks
Description 给定$n$个数和$b$个盒子,放一些数到盒子中,使得盒子不为空.每个盒子中的数是一样的,一个数可以被放到多个盒子中. 从每个盒子中取一个数,组成一个$b$位数,如果这个数$mo ...
- CodeForces 621C Wet Shark and Flowers
方法可以转化一下,先计算每一个鲨鱼在自己范围内的数能被所给素数整除的个数有几个,从而得到能被整除的概率,设为f1,不能被整除的概率设为f2. 然后计算每相邻两只鲨鱼能获得钱的期望概率,f=w[id1] ...
随机推荐
- 关于vim复制剪贴粘贴命令的总结-转
最近在使用vim,感觉很好很强大,但是在使用复制剪切粘贴命令是,碰到了一些小困惑,网上找了一些资料感觉很不全,讲的也不好,遂自己进行实践并总结了. 首先是剪切(删除): 剪切其实也就顺带删除了所选择的 ...
- UE4之Slate: App启动与最外层Runtime结构
UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...
- keybd_event模拟键盘按键,mouse_event怎么用
从 模仿UP主,用Python实现一个弹幕控制的直播间! - 蛮三刀酱 - 博客园 (cnblogs.com) 知道了 PyAutoGUI: * Moving the mouse and clicki ...
- 【leetcode】122.Best Time to Buy and Sell Stock II(股票问题)
You are given an integer array prices where prices[i] is the price of a given stock on the ith day. ...
- go channel 概述 - 管道
概述 unix/linux OS 的一个进程的输出可以是另一个进程的输入,这些进程使用stdin与stdout设备作为通道,在进程之间传递数据. 同样的,GO中有io.Reader与io.Writer ...
- ORACLE 获取执行计划的方法
一.获取执行计划的6种方法(详细步骤已经在每个例子的开头注释部分说明了): 1. explain plan for获取: 2. set autotrace on : 3. statistics_lev ...
- 开源低代码开发平台entfrm2.1.0更新
开源低代码开发平台entfrm2.1.0更新 新功能 代码生成支持主子表,支持预览: 新增多应用顶部菜单与左侧菜单联动: element-ui升级到2.15.1: 新增表单管理,集成avue-from ...
- 【编程思想】【设计模式】【结构模式Structural】front_controller
Python版 https://github.com/faif/python-patterns/blob/master/structural/front_controller.py #!/usr/bi ...
- Linux运维实战之磁盘分区、格式化及挂载(一)
在网络系统中,磁盘和文件系统管理是两个非常基本.同时也是非常重要的管理任务,特别是文件系统管理,因为它与用户权限和整个网络系统的安全息息相关.本次博文的主题是关于Linux系统中磁盘分区.格式化及挂载 ...
- java通过反射获取Java对象属性值
说明: 作为反射工具类,通过对象和属性的名字获取对象属性的值,如果在当前对象属性没有找到,依次向上收集所有父类的属 性,直到找到属性值,没有找到返回null: 代码: 1.classUtil pack ...