传送门:bzoj3026
题解
题意不清楚,解释一下:
对于一个高度为
n
n
n的阶梯柱状图:
x
xx
xxx
求用
n
n
n个长方形覆盖全图(不重叠,且完全覆盖)的总方案数
f
(
n
)
f(n)
f(n),答案即
K
f
(
n
)
K^{f(n)}
Kf(n)
每行最后一个方格显然是属于不同长方形的,考虑染了最上一行后的变化情况:
A
AB
CCC
假设选择的是A区域这个长方形,显然接下来不能存在长方形跨过BC区域。
所以方案数 f ( n ) = ∑ i = 0 n − 1 f ( i ) f ( n − 1 − i ) f(n)=\sum\limits_{i=0}^{n-1}f(i)f(n-1-i) f(n)=i=0∑n−1f(i)f(n−1−i)
所以 f ( n ) f(n) f(n)为卡特兰数 ( n + n n ) − ( n + n n − 1 ) \binom {n+n}{n}-\binom{n+n}{n-1} (nn+n)−(n−1n+n)
接下来就是求解 f ( n ) ( m o d φ ( m o d ) ) f(n)\pmod {\varphi( mod)} f(n)(modφ(mod))的值,将 φ ( m o d ) \varphi( mod) φ(mod)质因数分解后以每个质因数为模卢卡斯定理求出 ( n + n n ) \binom {n+n}{n} (nn+n)和 ( n + n n − 1 ) \binom {n+n}{n-1} (n−1n+n),再CRT合并即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000123,N=1e5+10,M=mod-1;
typedef long long ll;
const int mo[6]={2,3,11,2089,7253},w=5;
int n,K,ans,frc[10000],bs,p;
inline int sqr(int x){return (ll)x*x%p;}
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=(ll)x*x%p)
if(y&1) re=(ll)re*x%p;
return re;
}
void exgcd(int a,int b,int &x,int &y)
{
if(!b) {x=1;y=0;return;}
exgcd(b,a%b,y,x);y-=(a/b)*x;
}
inline int inv(int n)
{
int x,y;
exgcd(n,p,x,y);
return (x%p+p)%p;
}
inline int C(int n,int m)
{
if(m>n) return 0;
int i,re=1,x,y;
for(i=1;i<=m;++i){
x=(ll)(n-i+1)*inv(i)%p;
re=(ll)re*x%p;
}
return re;
}
inline int lucas(int n,int m)
{
if(!m) return 1;
if(n<p) return C(n,m);
return (ll)lucas(n/p,m/p)*C(n%p,m%p)%p;
}
int sol(int n)
{return (lucas(n+n,n)-lucas(n+n,n-1)+M)%M*(ll)(M/p)%M*(ll)fp((M/p)%p,p-2)%M;}
int main(){
int i;
while(scanf("%d%d",&n,&K)!=EOF){
for(ans=i=0;i<5;++i) {p=mo[i];ans=(ans+sol(n))%M;}
p=mod;printf("%d\n",fp(K,ans));
}
return 0;
}