• 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 }
  • 相关阅读:
    android Logger 一二三
    深挖android low memory killer
    ios CoreBluetooth 警告 is being dealloc'ed while pending connection
    iOS 国际化多语言设置 xcode7
    iOS 控制单个控制器旋转
    ios 开发 收起键盘的小技巧
    xcode ___gxx_personality_v0" 编译错误
    xcode6 AsynchronousTesting 异步任务测试
    xcode6 framework missing submodule xxx 警告
    iOS AVCaptureVideoDataOutputSampleBufferDelegate 录制视频
  • 原文地址:https://www.cnblogs.com/zzqc/p/9037845.html
Copyright © 2020-2023  润新知