一如既往的垃圾,又回到了那个场场垫底的自己,明明考场上都想到正解了,但是就是拿不到分,可能是互奶把rp用光了吧以后一定加强训练代码能力。

T1:

考场上一直yy矩阵快速幂,虽然自己矩阵快速幂一点都不会还是硬着头皮yy,发现不可做之后并没有及时转化思路,但其实自己预处理的数组就是正解。

切记:不仅矩阵快速幂是log的,普通快速幂也是2333

然后这题其实很水啊,我们设$dp[i][j]$为前$i$列放$j$个棋子的方案数,然后枚举最后一列放多少个棋子就好了。

转移方程为$dp[i][j]=\sum{dp[i-1][j-k]*C_n^k}$,这样转移m列显然不行,考虑性质,第$i$列和第$i+kn$列的摆放方式一定相同,所以后面的组合数乘还有多少这样的列就好了即${C_n^k}^{\frac{m-i}{n}+1}$,但这样的复杂度是$O(n^4logn)$的,发现组合数可以预处理,于是去掉了log

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10,mod=1e9+7;
 4 #define int long long
 5 int n,m,c,fac[N],inv[N];
 6 int f[105][105*105],pre[105][105*105];
 7 int min(int a,int b){
 8     return a<b?a:b;
 9 }
10 int qpow(int a,int b){
11     int ans=1;
12     while(b){
13         if(b&1) ans=ans*a%mod;
14         b>>=1;
15         a=a*a%mod;
16     }
17     return ans%mod;
18 }
19 int C(int a,int b){
20     return fac[a]*inv[b]%mod*inv[a-b]%mod;
21 }
22 signed main(){
23     fac[0]=1;
24     for(int i=1;i<=10001;++i) fac[i]=fac[i-1]*i%mod;
25     inv[10001]=qpow(fac[10001],mod-2);
26     for(int i=10001;i;--i) inv[i-1]=inv[i]*i%mod;
27     scanf("%lld%lld%lld",&n,&m,&c);
28     f[0][0]=1;
29     for(int i=0;i<=n;++i) for(int j=0;j<=max(n,c);++j) pre[i][j]=qpow(C(n,j),(m-i)/n+1)%mod;
30 //    for(int i=1;i<=n;++i,cout<<endl) for(int j=1;j<=n;++j) cout<<pre[i][j];
31     for(int i=1;i<=n;++i){
32         for(int j=0;j<=c;++j){
33             for(int k=0;k<=min(n,j);++k){
34                 (f[i][j]+=f[i-1][j-k]*pre[i][k]%mod)%=mod;
35 //                cout<<pre[i][k]<<" "<<qpow(C(n,k),(m-i)/n+1)<<endl;
36             }
37         }
38     }
39     printf("%lld",f[n][c]%mod);
40 }
41 /*
42 2 3 1
43 */
chess

相关文章:

  • 2021-06-29
  • 2022-01-21
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-15
  • 2021-12-15
  • 2021-12-15
  • 2021-12-15
  • 2021-12-15
  • 2021-11-22
  • 2022-02-04
相关资源
相似解决方案