这题题意什么鬼呀。。
X
XX
XXX
XXXX
XXXXX
意思是形如这种的楼梯,然后要分成n块矩形。
显然每一行最后一个X会分属不同的矩形。
那么我们考虑最上面那个点所属的矩形,
X
XA
XAA
CCCC
CCCCC
那么其实它会把楼梯分成两部分,显然是不会有矩形跨越A和C的。因为假如说有矩形从A那里下来了,那么他显然不能包含最左面的C,那么最左边的C就无法被包含了。像这样:
X
XA
XOO
COOC
CCCCC
所以说这两部分是独立的。
那么就可以dp啦。
f(n)=∑i=1nf(i−1)∗f(n−i)f(0)=1
这就是经典的catlan数的式子啦,所以 f(n)=(2nn)−(2nn−1)=(2nn)n+1
那么答案就是 kf(n)
所以就又成了经典的组合数取模问题,对p-1分解质因数即可分别求组合数然后crt合并即可。
#include<cstdio>
#include<iostream>
using namespace std;
#include<algorithm>
#include<cstring>
const int p[]={2,3,11,2089,7253};
const int Mod=1000000123;
typedef long long LL;
LL power(LL prod,int x,int Mod)
{
//printf("power(%I64d,%d,%I64d)\n",prod,x,Mod);
LL ans=1;
for(;x;x>>=1)
{
if(x&1)ans=ans*prod%Mod;
prod=prod*prod%Mod;
}
return ans;
}
int cal_exp(int n,int Mod)
{
int ans=0;
for(;n;n/=Mod)ans+=n/Mod;
return ans;
}
const int P=10000;
LL factor[P];
LL fac(int n,int Mod)
{
factor[0]=1;
for(int i=1;i<Mod;++i)factor[i]=factor[i-1]*i%Mod;
LL ans=1;
for(;n;n/=Mod)ans=ans*power(factor[Mod-1],n/Mod,Mod)%Mod*factor[n%Mod]%Mod;
return ans;
}
LL C(int n,int m,int Mod)
{
LL ans;
if(cal_exp(n,Mod)>cal_exp(m,Mod)+cal_exp(n-m,Mod))ans=0;
else ans=fac(n,Mod)*power(fac(m,Mod),Mod-2,Mod)%Mod*power(fac(n-m,Mod),Mod-2,Mod)%Mod;
//printf("C(%d,%d,%d)=%I64d\n",n,m,Mod,ans);
return ans;
}
LL work(int n,int m,int Mod)
{
//puts("--------");
LL ans=0;
for(int i=5;i--;)ans=(ans+power(Mod/p[i],p[i]-1,Mod)*C(n,m,p[i]))%Mod;
//printf("C(%d,%d,%d)=%I64d\n",n,m,Mod,ans);
//for(int i=5;i--;)printf("%d:%I64d %d\n",p[i],ans%p[i],20%p[i]);
return ans;
}
int main()
{
freopen("bzoj3026.in","r",stdin);
freopen("bzoj3026.out","w",stdout);
int n,k;
while(~scanf("%d%d",&n,&k))cout<<power(k,((work(n*2,n,Mod-1)-work(n*2,n-1,Mod-1))%(Mod-1)+Mod-1)%(Mod-1),Mod)<<endl;
}
总结:
①一定要注意在指数的话应该是模
φ(p)
。
②除的时候一定要想清楚有没有逆元。