【BZOJ4870】组合数问题 [矩阵乘法][DP]

组合数问题

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

Description

  

Input

  第一行有四个整数 n, p, k, r,所有整数含义见问题描述。

Output

  一行一个整数代表答案。

Sample Input

  2 10007 2 0

Sample Output

  8

HINT

  1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1

Solution

  首先,不难发现,题目的本质是:从n*k个中选模k等于r个的方案数,那么轻易地写出了暴力DP:f[i][j]=f[i-1][j]+f[i-1][(j-1+k)%k]

  然后套个矩阵乘法优化一下即可。

Code

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64;

const int ONE = 55;

int n,MOD,num,r;

inline s64 get()
{
        s64 res=1,Q=1;  char c;
        while( (c=getchar())<48 || c>57)
        if(c==‘-‘)Q=-1;
        if(Q) res=c-48;
        while((c=getchar())>=48 && c<=57)
        res=res*10+c-48;
        return res*Q;
}

struct Matrix
{
        s64 v[ONE][ONE];
        friend Matrix operator *(Matrix a,Matrix b)
        {
            Matrix record;
            for(int i=0;i<num;i++)
            for(int j=0;j<num;j++)
            {
                record.v[i][j]=0;
                for(int k=0;k<num;k++)
                record.v[i][j] = (s64)(record.v[i][j] + a.v[i][k]*b.v[k][j] % MOD) % MOD;
            }
            return record;
        }
};
Matrix B,Ans;

Matrix Quickpow(Matrix a,s64 b)
{
        Matrix res;
        for(int i=0;i<num;i++) res.v[i][i] = 1;
        while(b)
        {
            if(b&1) res = res*a;
            a = a*a;
            b>>=1;
        }
        return res;
}

int main()
{
        n=get();    MOD=get();    num=get();    r=get();
        for(int i=0;i<num;i++)
        {
            B.v[i][i]++;
            B.v[((i-1)%num+num)%num][i]++;
        }

        Ans = Quickpow(B, (s64)n*num);

        cout<<Ans.v[0][r];

}

时间: 2024-11-04 06:42:15

【BZOJ4870】组合数问题 [矩阵乘法][DP]的相关文章

[矩阵乘法][DP]Vijos1067 Warcraft III 守望者的烦恼

题目梗概 n个单位的路程,主角每次最多可以走k个单位(也就是每次可以走1-k个单位),问最后到第n个监狱的方法数. 思考 DP转移方程并不难推导: dp[i]表示第i个监狱的方法数 $dp\left [ i \right ] = dp\left [ i-1 \right ] + dp\left [ i-2 \right ]\cdots \cdots + dp\left [ i-k-1 \right ]$ 但是这个n有点太大了,所以我们需要对DP方程进行优化. 仔细观察转移方程会发现,每次都是加上

JZYZOJ 1542 [haoi2015]str 矩阵乘法 dp

http://172.20.6.3/Problem_Show.asp?id=1542 dp+矩阵乘法思路hin好想,对于我这种题目稍微学术就几乎什么也不会的人来说唯一的难点在于读题,因为一心想着划水题目没有看清楚,样例wa了一会最后仔细读题发现自己g的操作看错了,非常智障了 代码 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #inclu

bzoj1009 [HNOI2008] GT考试 矩阵乘法+dp+kmp

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4542  Solved: 2815[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..

矩阵乘法&amp;&amp;dp加速矩阵的思路(E. Wet Shark and Blocks)

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,

ZOJ - 3216:Compositions (DP&amp;矩阵乘法&amp;快速幂)

We consider problems concerning the number of ways in which a number can be written as a sum. If the order of the terms in the sum is taken into account the sum is called a composition and the number of compositions of n is denoted by c(n). Thus, the

【BZOJ2510】弱题 期望DP+循环矩阵乘法

[BZOJ2510]弱题 Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个球标号为k(k < N),则将它重新标号为k + 1:若这个球标号为N,则将其重标号为1.(取出球后并不将其丢弃) 现在你需要求出,经过K次这样的操作后,每个标号的球的期望个数. Input 第1行包含三个正整数N,M,K,表示了标号与球的个数以及操作次数. 第2行包含N个

BZOJ 3329 Xorequ 数位DP+矩阵乘法

题目大意:给定n,求[1,n]以内以及[1,2^n]以内有多少x满足x^3x=2x x^3x=2x等价于x^2x = 3x 而3x=x+2x 且2x=x<<1 故x满足条件当且仅当x&(x<<1)=0 故x的二进制拆分中任意两个1不相邻 令f[i]为i位数中最高位为0的满足条件的数的数量 g[i]为i位数中最高位为1的满足条件的数的数量 则显然有 f[i+1]=f[i]+g[i] g[i+1]=f[i] 于是第一问数位DP 第二问矩阵乘法即可 #include <cs

【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <

【BZOJ-4386】Wycieczki DP + 矩阵乘法

4386: [POI2015]Wycieczki Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 197  Solved: 49[Submit][Status][Discuss] Description 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. Input 第一行包含三个整数n,m,k(1<=n<=40,1&