zoukankan      html  css  js  c++  java
  • Codeforces 621E—Wet Shark and Blocks(数位DP+矩阵快速幂优化)

    题意:一个b位的数Y,每一位的数可以从题目给的n个数里面选,问有多少种方案使得Y mod x == k?

    思路:数位dp,另dp[i][k]表示前i位模x结果为k的方案数,则转移方程为:dp[i][(k*10+j)%x]+=dp[i-1][k]*num[j](0<=j<=9),num[j]为题目所给数据j的个数。显然一维高达1e9没法正常递推,所以用矩阵快速幂优化。构造一个100*100的初始矩阵,第一行代表第一位%x等于j的方案数(0<=j<=99),接下来是构造矩阵,矩阵的规模也是100*100。假设(i*10+j)%x=now,(0<=i<=99,0<=j<=9),那么取下一位后的结果是now的增加的方案数就是满足条件的num[j]的和。

     1 #include <iostream>
     2 #include <queue>
     3 #include <stack>
     4 #include <cstdio>
     5 #include <vector>
     6 #include <map>
     7 #include <set>
     8 #include <bitset>
     9 #include <algorithm>
    10 #include <cmath>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <string>
    14 #include <sstream>
    15 #include <time.h>
    16 #define x first
    17 #define y second
    18 #define pb push_back
    19 #define mp make_pair
    20 #define lson l,m,rt*2
    21 #define rson m+1,r,rt*2+1
    22 #define mt(A,B) memset(A,B,sizeof(A))
    23 using namespace std;
    24 typedef long long LL;
    25 const double PI = acos(-1);
    26 const int N=100;
    27 const LL mod=1e9+7;
    28 const int inf = 0x3f3f3f3f;
    29 const LL INF=0x3f3f3f3f3f3f3f3fLL;
    30 LL n,b,k,x,p;
    31 LL num[20];
    32 struct Mat
    33 {
    34     LL mat[N][N];
    35 }F,goal;
    36 Mat operator * (Mat a,Mat b)
    37 {
    38     Mat c;
    39     mt(c.mat,0);
    40     for(int i=0; i<N; i++)
    41     {
    42         for(int j=0; j<N; j++)
    43         {
    44             for(int k=0; k<N; k++)
    45             {
    46                 c.mat[i][j]=(c.mat[i][j]+(a.mat[i][k]*b.mat[k][j])%mod)%mod;
    47             }
    48         }
    49     }
    50     return c;
    51 }
    52 Mat pow_mod(Mat a,LL n)
    53 {
    54     Mat ans;
    55     mt(ans.mat,0);
    56     for(int i=0;i<N;i++)ans.mat[i][i]=1;
    57     while(n)
    58     {
    59         if(n&1)ans=ans*a;
    60         a=a*a;
    61         n/=2;
    62     }
    63     return ans;
    64 }
    65 int main()
    66 {
    67 #ifdef Local
    68     freopen("data.txt","r",stdin);
    69 #endif
    70     ios::sync_with_stdio(false);
    71     cin.tie(0);
    72     cin>>n>>b>>k>>x;
    73     mt(num,0);
    74     mt(F.mat,0);
    75     mt(goal.mat,0);
    76     for(int i=0; i<n; i++)
    77     {
    78         cin>>p;
    79         num[p]++;
    80     }
    81     for(LL i=0; i<N; i++)
    82     {
    83         for(LL j=0; j<=9; j++)
    84         {
    85             LL w=((i*10)%x+j)%x;
    86             F.mat[i][w]+=num[j];
    87         }
    88     }
    89     for(LL i=0; i<=9; i++)
    90     {
    91         goal.mat[0][i%x]+=num[i];
    92     }
    93     goal=goal*pow_mod(F,b-1);
    94     cout<<goal.mat[0][k]<<endl;
    95 #ifdef Local
    96     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    97 #endif
    98 }
    View Code
  • 相关阅读:
    第三周作业
    第二周作业
    第一周作业
    预备作业3
    预备作业2
    预备作业01
    ## 20155336 2016-2017-2《JAVA程序设计》第十周学习总结
    20155336 2016-2017-2《JAVA程序设计》第九周学习总结
    ## 20155336 2016-2017-2《JAVA程序设计》第八周学习总结
    20155336 2016-2017-2《JAVA程序设计》第七周学习总结
  • 原文地址:https://www.cnblogs.com/27sx/p/6492590.html
Copyright © 2011-2022 走看看