[bzoj3026] 楼梯染色 解题报告
2016-09-11 16:12
218 查看
这题题意什么鬼呀。。
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合并即可。
总结:
①一定要注意在指数的话应该是模φ(p)。
②除的时候一定要想清楚有没有逆元。
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)。
②除的时候一定要想清楚有没有逆元。
相关文章推荐
- BZOJ4033[HAOI2015] 树上染色 解题报告【树上DP】
- bzoj 2243 染色 树链剖分 解题报告
- [BZOJ2243][SDOI2011]染色 解题报告|树链剖分
- BZOJ 3727 PA2014 树DP 解题报告
- [Usaco2011][bzoj2442][洛谷2527]修剪草坪解题报告(dp,贪心,单调队列)
- BZOJ 2201 期望DP 解题报告
- BZOJ 3754 Tree之最小方差树 解题报告
- BZOJ 2131 数据结构优化DP 解题报告
- bzoj 1012 单调队列 解题报告
- BZOJ 3223 Splay 解题报告
- BZOJ2002 [Hnoi2010]Bounce 弹飞绵羊 解题报告【数据结构】【分块】
- [BZOJ1025] [SCOI2009]游戏 解题报告
- bzoj 4034 树上操作 树链剖分 解题报告
- BZOJ4009: [HNOI2015]接水果 解题报告
- BZOJ 3993 [SDOI 2015] 星际战争 解题报告
- BZOJ 4619 Swap Space 解题报告
- BZOJ 4004 [JLOI 2015] 装备购买 解题报告
- BZOJ 1072 [SCOI 2007] 状压DP 解题报告
- BZOJ 1040 [ZJOI 2008] 树DP 解题报告
- [BZOJ2946][Poi2000]公共串解题报告|后缀自动机