【38.24%】【codeforces 621E】 Wet Shark and Blocks
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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 choose exactly one digit from each block and concatenate all of those digits together to form one large integer. For example, if he chooses digit 1 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 3 ways 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, 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.
Output
Print the number of ways to pick exactly one digit from each blocks, such that the resulting integer equals k modulo x.
Examples
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.
【题解】
有b个盒子;
每个盒子里都有n个数字;
让你从每个盒子中都取出一个数字1..9;
顺序组成长度为b的数字;
问数字取余结果为k的数字个数;
预处理出每个数字有多少个;
如果b没那么大的话可以这样写;
设dp[i][j]表示前i个数字组成的数取余结果为j的方案数
dp[i+1][(j*10+t)%k]+=dp[i][j]*num[t];
对于每一个转移;
其实都是(j*10+t)%k += t这个数字的个数*dp[i][j];
即每个转移都是一样的;
则一开始预处理出一个初始矩阵a[i][j];
这个矩阵表示的是
一开始余数为i的时候利用1-9这几个数字到余数为j的方案数增加量;
(还记得图论的从某个点到另外一个点恰好走k步的方案吗;http://blog.csdn.net/harlow_cheng/article/details/52615106我们一开始的初始矩阵也是任意两个点之间能否到达->即从i点到j点的方案增加量,(我们一开始是设为1表示联通的,那不正是方案增加量吗?)),这里也可以看成是知道任意两点之间(0..x-1)->(0..x-1)的连通关系,但是初始的时候任意两点联通对方案的增加量变成了一个可能大于1的数字);
求矩阵的b次幂;
最后的那个矩阵是为了加深理解;可以不用乘;->矩阵E->从0->0一开始的方案都为1,即都不变;
乘一下就能够和答案联系在一起了;
即从一开始取余为0->…->k
最后输出ans[0][k];
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#define lson L,m,rt<<1
#define rson m+1,R,rt<<1|1
#define LL long long
using namespace std;
const int MAXMOD = 120;
const LL MOD = 1e9+7;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
struct abc
{
LL jz[MAXMOD][MAXMOD];
};
LL num[10];
int n,b,k,x;
LL f[MAXMOD];
abc a;
void input_LL(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)) t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void input_int(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)) t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
abc jc(abc a, abc b)
{
abc c;
for (int i = 0; i <= x-1; i++)
for (int j = 0; j <= x-1; j++)
{
c.jz[i][j] = 0;
for (int k = 0; k <= x-1; k++)
c.jz[i][j] = (c.jz[i][j] + a.jz[i][k] * b.jz[k][j])%MOD;
}
return c;
}
abc ksm(int x)
{
if (x == 1)
return a;
abc temp;
temp = ksm(x>>1);
temp = jc(temp,temp);
if (x&1)
temp = jc(temp,a);
return temp;
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_int(n);input_int(b);input_int(k);input_int(x);
for (int i = 1;i <= n;i++)
{
int temp;
input_int(temp);
num[temp]++;
}
int now = 0;
for (int i = 0;i<=x-1;i++)
for (int j = 1;j <= 9;j++)
a.jz[i][(i*10+j)%x]=(a.jz[i][(i*10+j)%x] + num[j])%MOD;
abc ans = ksm(b);
abc E;
E.jz[0][0] = 1;
ans = jc(E,ans);
printf("%I64d\n",ans.jz[0][k]);
return 0;
}
【38.24%】【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 ...
- JAVA 基础编程练习题24 【程序 24 根据输入求输出】
24 [程序 24 根据输入求输出] 题目:给一个不多于 5 位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. package cskaoyan; public class cskaoya ...
- CODEFORCEs 621E. Wet Shark and Blocks
E. Wet Shark and Blocks time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- 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%】【POJ 1201】Intervals
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25902 Accepted: 9905 Description You are ...
- 【 BowWow and the Timetable CodeForces - 1204A 】【思维】
题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...
- Codeforces Round #341 (Div. 2) E - Wet Shark and Blocks
题目大意:有m (m<=1e9) 个相同的块,每个块里边有n个数,每个数的范围是1-9,从每个块里边取出来一个数组成一个数,让你求组成的方案中 被x取模后,值为k的方案数.(1<=k< ...
- cf 621E. Wet Shark and Blocks
神奇,矩阵乘法23333333333333333 递推式是很简单的(连我这种不会DP的人都写出来了.) 需要求出的是转移矩阵(还是叫系数矩阵的),也是最这个东西用快速幂. 这个东西的i,j大概就表示从 ...
- 【24.17%】【codeforces 721D】Maxim and Array
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- 三星Galaxy Tab S2上市,压制苹果之心凸显
平板市场正在迎来史上最为关键的一次PK,众所周知,平板市场的苹果和三星一直是行业的领头羊,而在激烈的竞争中.三星平板似乎后劲更足.众多性能优异的产品频频推出.平板之王的称谓呼之欲出. 去年三星 ...
- Android Material风格的应用(四)--FloatActionButton
添加 FloatActionButton和SnackBar Android Material风格的应用(一)--AppBar TabLayoutAndroid Material风格的应用(二)--Re ...
- 观察者模式 VS 责任链模式
为什么要把观察者模式和责任链模式放在一起对比呢?这两个模式没有太多的相似性呀,真没有嘛?有相似性,我们在观察者模式中也提到了触发链(也叫做观察者链)的问题,一个具体的角色既可以是观察者,也可以是被观察 ...
- orabbix自定义监控oracle
前提:安装orabbix 好后能正常运行, 检验条件(1). 最新数据有数据 (2).图形有显示 (3).日志不报错 /opt/orabbix/logs/orabbix.log 添加方法: 1. ...
- 6.4 Android硬件访问服务编写HAL代码
JNI向上提供本地函数,向下加载HAL文件,并调用HAL的函数: HAL负责访问驱动程序执行硬件操作 JNI和HAL都是用c语言或者C++语言编写的,JNI加载HAL的实质就是使用dlopen加载动态 ...
- Vertx简介
今天看了一篇很不错的关于Vertx的简介,转载下. 原文链接:http://www.csdn.net/article/2015-12-21/2826533?utm_source=tuicool& ...
- [array] leetCode-26. Remove Duplicates from Sorted Array - Easy
26. Remove Duplicates from Sorted Array - Easy descrition Given a sorted array, remove the duplicate ...
- 关于stm32的输入输出
https://blog.csdn.net/u011556018/article/details/72629082
- SDI与ASI 接口具体解释介绍
分量编码 在对彩色电视信号进行数字化处理和传输是.一种经常使用的方式是分别对其3个分量(Y,R-Y.B-Y)进行数字化编码.这就是分量分量编码.另外还有全信号编码,全信号编码是对彩色全电视信号直接进行 ...
- 用Eclipse替代Keil&IAR来开发ARM应用(升级版)
Eclipse GNU ARM Plugin 2014/7/16 作者 kiya 几个月前写了一篇<),想自己丰衣足食的参考我的上一篇文章,以及GNU ARM的官网. 用Eclipse替代Kei ...