• BZOJ 4870[HEOI2017]组合数问题


    题面:

    4870: [Shoi2017]组合数问题

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 484  Solved: 242
    [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个物品中选出j个的方案数

    f[i][j]=f[i-1][j]+f[i-1][j-1]

    变形后得到f[i+j][x+y]+=f[i][x]*f[j][y]然后就可以高高兴兴的矩阵快速幂了

    时间复杂度O(k3log2n)

     1 #include<stdio.h>
     2 #include<string.h>
     3 using namespace std;
     4 #define LL long long
     5 int n,p,k,r;
     6 int add(int x,int y)
     7 {   
     8     x+=y;
     9     return x>=k?x-k:x;
    10 }
    11 struct martix
    12 {
    13     int a[51];
    14     martix()
    15     {
    16         memset(a,0,sizeof(a));
    17     }
    18     martix operator * (const martix&b) const
    19     {
    20         martix ans;
    21         for(int i=0;i<k;i++)
    22             for(int j=0;j<k;j++)
    23                 ans.a[add(i,j)]=(ans.a[add(i,j)]+1LL*a[i]*b.a[j])%p;
    24         return ans;
    25     }   
    26 };
    27 int main()
    28 {
    29     scanf("%d%d%d%d",&n,&p,&k,&r);
    30     martix ans,x;
    31     ans.a[0]=x.a[0]=1;
    32     ++x.a[k==1?0:1];
    33     for(LL i=1LL*n*k;i;i>>=1,x=x*x)
    34         if(i&1)
    35             ans=ans*x;
    36     printf("%d",ans.a[r]);  
    37 }
    BZOJ 4870
  • 相关阅读:
    linux 如何显示一个文件的某几行(中间几行)
    Cookie——Javascript
    CSS——4种定位
    Javascript——DOM
    javascript之八——BOM
    Javascript——闭包、作用域链
    Struct2
    javaweb——Servlet作为控制器
    排序算法——快排思想
    java——获取从控制台输入的数据的方法
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7241822.html
Copyright © 2020-2023  润新知