zoukankan      html  css  js  c++  java
  • BZOJ 4870

    4870: [Shoi2017]组合数问题

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 723  Solved: 379
    [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

    Source

    黑吉辽沪冀晋六省联考

    HINT

     

     矩阵快速幂可以求组合数

    然后这道题的递推什么的其实也是差不多的道理

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define N 50
    #define ll long long
    using namespace std;
    int read()
    {
        int f=1,x=0;char s=getchar();
        while(s<'0' || s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0' && s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    ll n,mod,k,r;
    struct matrix
    {
        ll a[N][N];
        inline void clear()
        {
            memset(a,0,sizeof(a));
        }
        inline void print()
        {
            for(int i=0;i<k;i++)
            {
                for(int j=0;j<k;j++)printf("%d ",a[i][j]);
                printf("
    ");
            }
            printf("
    ");
        }
    }e,tr,ans;
    inline matrix operator * (matrix a,matrix b)
    {
        matrix c; c.clear();
        for(int i=0;i<k;i++)for(int j=0;j<k;j++)for(int s=0;s<k;s++)
            c.a[i][j]=(c.a[i][j]+(a.a[i][s]%mod)*(b.a[s][j]%mod))%mod;
        return c;
    }
    inline matrix pow(matrix a,ll p)
    {
        matrix ret=e;
        while(p)
        {
            if(p&1)ret=ret*a;
            a=a*a;
            p>>=1;
        }
        return ret;
    }
    /*
    void debug()
    {
        matrix x=e;
        for(int i=0;i<n;i++)x=x*tr,x.print();
    }*/
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&mod,&k,&r);
        ans.a[0][0]=1;
        for(int i=0;i<k;i++)
            e.a[i][i]=1,tr.a[i][i]++,tr.a[i][(i+1)%k]++;
        n*=k;
        
        //debug();
        tr=pow(tr,n);
        ans=ans*tr;
        //ans.print();
        printf("%lld
    ",(ans.a[0][r]+mod)%mod);
        
        //tr=tr*tr;
        //tr.print();
        return 0;
    }
  • 相关阅读:
    Linux负载均衡--LVS(IPVS)主要算法实现分析
    使用alarm控制阻塞connect()超时的示例
    使用select控制非阻塞connect()超时的示例
    再出发
    nulls_hlist原理 和 tcp连接查找
    linux支持大容量硬盘
    Nmap扫描原理(下)
    linux常用命令
    Linux下面自动清理超过指定大小的文件
    Memcached介绍
  • 原文地址:https://www.cnblogs.com/fdfzhyf/p/8566956.html
Copyright © 2011-2022 走看看