zoukankan      html  css  js  c++  java
  • P3746 [六省联考2017]组合数问题 矩阵乘法

    题意:

    (C_{nk}^r+C_{nk}^{k+r}dots+C_{nk}^{nk+r}dots) 的和 (mod p) 的值

    范围&性质: (1le n,ple 10^9,1le r< kle 50)

    分析:

    • 暴力

    各种特判+Lucas+暴力组合数 ( o) 80pts 这省选真良心

    • 正解

    由于 (r,k) 很小,所以要么容斥掉不合法情况,要么就矩阵乘优化递推

    但是单纯的矩阵乘每次会漏掉一些信息,比如无法由 (f_{i-1,j-1}) 直接更新出 (f_{i,j-1}) ,因为缺少了一项 (f_{i-1,j-2})

    所以构造的矩阵乘法是类似循环的,即第 (k) 个数更新后会变成下一次矩乘中的第一项,这样就不会存在信息被漏掉的情况,因为原来的复杂度(O(k^3 log nk))

    其实有更优秀的(O(k^2log nk))的做法

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	inline int read()
    	{
    		int x=0,f=1;char ch=getchar();
    		while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    		while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    		return x*f;
    	}
    	
    	const int maxn = 55;
    	int n,k,mod,r;
    	
    	struct mat
    	{
    		long long c[maxn][maxn];
    		mat(){memset(c,0,sizeof(c));}
    		mat operator *(const mat &b)const
    		{
    			mat res;
    			for(int i=1;i<=k;i++)
    			{
    				for(int j=1;j<=k;j++)
    				{
    					for(int l=1;l<=k;l++)
    					{
    						res.c[i][l]=(res.c[i][l]+c[i][j]*b.c[j][l])%mod;
    					}
    				}
    			}
    			return res;
    		}
    	}trans,ans;
    	
    	mat qpow(mat x,long long y)
    	{
    		mat res;
    		for(int i=1;i<=k;i++) res.c[i][i]=1;
    		while(y)
    		{
    			if(y&1) res=res*x;
    			x=x*x;
    			y>>=1;
    		}
    		return res;
    	}
    	
    	void work()
    	{
    		n=read();mod=read();k=read();r=read();
    		for(int i=1;i<=k;i++)
    		{
    			trans.c[i][i]=1;
    			if(i!=k) trans.c[i+1][i]+=1;
    			else trans.c[1][i]+=1;
    		}
    		for(int i=1;i<=k;i++) ans.c[i][i]=1;
    		ans=ans*qpow(trans,1ll*n*k);
    		printf("%lld
    ",ans.c[r+1][1]);
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
    
  • 相关阅读:
    python--随机生成汉字、数字
    PyCharm详细教程
    Struts2 笔记
    Servlet读取配置文件的三种方式
    Java笔记(十)
    Java笔记(九)
    Java笔记(八)
    Java笔记(七)
    Java笔记(六)
    Java笔记(五)
  • 原文地址:https://www.cnblogs.com/youth518/p/13958547.html
Copyright © 2011-2022 走看看