zoukankan      html  css  js  c++  java
  • bzoj-4870-组合dp+矩阵幂

    4870: [Shoi2017]组合数问题

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 829  Solved: 446
    [Submit][Status][Discuss]

    Description

    Input

    第一行有四个整数 n, p, k, r,所有整数含义见问题描述。
    1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1

    Output

    一行一个整数代表答案。

    Sample Input

    2 10007 2 0

    Sample Output

    8

    HINT

        注意到问题就是求从n*k件物品中选出若干件使得选出的物品的数量%K=R的不同方案个数,f[i][j]表示从前i件物品中选出若干件满足选出物品的数量%K=j的方案个数,有f[i][j]=f[i-1][j]+f[i-1][((j-1)+K)%K],显然利用矩阵幂可以快速转移,注意特判下K=1的情况。由于快速幂传参写的是int,但是N*K可能爆int一直WA最后才发现= =

        

     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<set>
     7 #include<map>
     8 #include<cmath>
     9 #include<ctime>
    10 #include<time.h> 
    11 #include<algorithm>
    12 #include<bits/stdc++.h>
    13 using namespace std;
    14 #define mp make_pair
    15 #define pb push_back
    16 #define debug puts("debug")
    17 #define LL  long long 
    18 #define ULL unsigned long long 
    19 #define uint unsigned int
    20 #define pii pair<int,int>
    21 #define eps 1e-10
    22 #define inf 0x3f3f3f3f
    23  
    24 LL N,P,K,R;
    25 LL qpow(LL a,LL b,LL p){
    26     LL r=1;
    27     while(b){
    28         if(b&1) r=r*a%p;
    29         a=a*a%p;
    30         b>>=1;
    31     }
    32     return r;
    33 }
    34 struct matrix{
    35     LL a[55][55];
    36     matrix(){
    37         memset(a,0,sizeof(a));
    38     }
    39     matrix operator*(matrix& tmp){
    40         matrix ans;
    41         for(int i=0;i<K;++i){
    42             for(int j=0;j<K;++j){
    43                 for(int k=0;k<K;++k){
    44                     (ans.a[i][k]+=a[i][j]*tmp.a[j][k])%=P;
    45                 }
    46             }
    47         }
    48         return ans;
    49     }
    50 }A,I;
    51 matrix qpow(matrix X,LL n){
    52     matrix ans=I;
    53     while(n){
    54         if(n&1) ans=ans*X;
    55         X=X*X;
    56         n>>=1;
    57     }
    58     return ans;
    59 }
    60 int main(){
    61  
    62     scanf("%lld%lld%lld%lld",&N,&P,&K,&R);
    63     N*=K;
    64     if(K==1){
    65         printf("%lld
    ",qpow(2,N,P));
    66     }
    67     else{
    68         for(int i=0;i<K;++i) I.a[i][i]=1;
    69         A.a[0][0]=A.a[0][K-1]=1;
    70         for(int i=1;i<K;++i){
    71             A.a[i][i]=A.a[i][i-1]=1;
    72         }
    73         matrix ans=qpow(A,N);
    74         printf("%lld
    ",ans.a[R][0]);
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    [学习笔记] SSD代码笔记 + EifficientNet backbone 练习
    [论文理解] CornerNet: Detecting Objects as Paired Keypoints
    [torch] torch.contiguous
    [tensorflow] tf2.0 简单例子
    [大坑]Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
    本机Jenkins的使用
    安全工具acunetix使用
    cv2.matchTemplate()函数的应用,匹配图片后画出矩形
    python将PNG格式的图片转化成为jpg
    Python实现FTP文件的上传和下载
  • 原文地址:https://www.cnblogs.com/zzqc/p/9037845.html
Copyright © 2011-2022 走看看