zoukankan      html  css  js  c++  java
  • [cf621E]Wet Shark and Blocks

    Description

    给定$n$个数和$b$个盒子,放一些数到盒子中,使得盒子不为空。每个盒子中的数是一样的,一个数可以被放到多个盒子中。

    从每个盒子中取一个数,组成一个$b$位数,如果这个数$mod;k=x$,则这是一种合法的方案。求方案数$mod;10^9+7$。

    Input

    第一行为$4$个数$n,b,x,k$。

    Output

    一行,表示方案数$mod 10^9+7$。

    Sample Input

    3 2 1 2
    3 1 2

    Sample Output

    6

    HINT

    $2;leq;n;leq;50000,1;leq;b;leq;10^9,0;leq;k;leq;100, x;geq;2,1;leq;a_i;leq;9$

    Solution

    显然序列中有用的条件仅有每个数出现的次数,记为$t[;]$。

    $f[i][j]$表示前$i$位数$mod;k$的值为$j$的方案数。

    $f[i+1][(j; imes;10+l)mod;n]=f[i][j]; imes;t[l]$。

    矩乘优化$DP$就能过了。

     1 #include<cmath>
     2 #include<ctime>
     3 #include<queue>
     4 #include<stack>
     5 #include<cstdio>
     6 #include<vector>
     7 #include<cstring>
     8 #include<cstdlib>
     9 #include<iostream>
    10 #include<algorithm>
    11 #define lld I64d
    12 #define K 15
    13 #define N 105
    14 #define M 1000000007
    15 using namespace std;
    16 typedef long long ll;
    17 struct matrix{
    18     ll a[N][N];int n,m;
    19 }a,b;
    20 ll t[K];
    21 int n,m,k,x;
    22 inline matrix mult(matrix a,matrix b){
    23     matrix c;c.n=a.n;c.m=b.m;
    24     for(int i=0;i<c.n;++i)
    25         for(int j=0;j<c.m;++j){
    26             c.a[i][j]=0;
    27             for(int k=0;k<a.m;++k)
    28                 c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%M;
    29         }
    30     return c;
    31 }
    32 inline matrix po(matrix a,int k){
    33     matrix c;c.n=a.n;c.m=a.m;
    34     for(int i=0;i<a.n;++i)
    35         for(int j=0;j<b.n;++j)
    36             if(i!=j) c.a[i][j]=0;
    37             else c.a[i][j]=1;
    38     while(k){
    39         if(k&1) c=mult(c,a);
    40         a=mult(a,a);k>>=1;
    41     }
    42     return c;
    43 }
    44 inline void init(){
    45     scanf("%d%d%d%d",&n,&m,&x,&k);
    46     for(int i=1,j;i<=n;++i){
    47         scanf("%d",&j);++t[j];
    48     }
    49     a.n=k;a.m=1;
    50     for(int i=1;i<=9;++i)
    51         a.a[i%k][0]+=t[i];
    52     b.n=b.m=k;
    53     for(int i=0,l;i<k;++i){
    54         for(int j=1;j<=9;++j){
    55             l=(i*10+j)%k;
    56             b.a[l][i]+=t[j];
    57         }
    58     }
    59     matrix c=mult(po(b,m-1),a);
    60     printf("%lld
    ",c.a[x][0]);
    61 }
    62 int main(){
    63     freopen("blocks.in","r",stdin);
    64     freopen("blocks.out","w",stdout);
    65     init();
    66     fclose(stdin);
    67     fclose(stdout);
    68     return 0;
    69 }
  • 相关阅读:
    使用Perl5获取有道词典释义
    Compress a Folder/Directory via Perl5
    为该目录以及子目录添加index.html
    学习Perl6: slice fastq file
    Javascript Regexp match and replace
    赋值运算符函数
    扑克牌顺子
    翻转单词顺序VS左旋转字符串
    和为S的两个数字VS和为S的连续正数序列
    数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/AireenYe/p/5814754.html
Copyright © 2011-2022 走看看