JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏
来源:互联网 发布:3m互助系统源码 编辑:程序博客网 时间:2024/05/16 06:30
Description
Data Constraint
Solution
我们设f[i][j]表示当前有i个格子恰好放了j种颜色的方案数,那么f[i][j]=f[i−1][j−1]∗(p−(j−1))+f[i−1][j]∗j 。我们设g[j]表示n个格子恰好放了j种颜色的方案数,那么g[j]=f[n][j]。对于假如上一列放了j种颜色,这一列放k种颜色,两列颜色的并集为x,那么造成的方案数为f1[j][k]=g[j]Cjp∗∑min(j+k,p)x=max(q,j,k)Cj+k−xj∗Cx−jp−j 。
解释一下:我们刚开始讲的g[j]包含的是p中任意j种颜色以任意顺序放入n个格子的方案数,那么对于p中任意j种颜色的方案数都是相等的,即g[j]Cjp 。明显对于j,k,它们的并集x最大是j+k,但由于最多只有p种颜色,所以x的上限为min(j+k,p) ,同时,x必须必j和k都大,由于题目要求交集必须大于q,所以x的下限为max(j,k,q) 。现在要求出k的颜色的组成,为了不重复不遗漏,我们对是否在j和k的交集的颜色分别求Cj+k−xj 表示j和k的交集有多少种情况(即在j中选出j和k的交集)。Cx−jp−j 表示在k中但不在j中有多少种情况(因为在k中必在x中,并且从除j外的剩余p-j中颜色中选出)。
现在我们设f2[i][k]表示现在做到第i列,第i列放了j种颜色的方案数,那么f2[1][k]=g[k],f2[i][k]=∑pj=1f2[i−1][k]∗f1[j][k] 。打一下矩阵乘法即可,时间复杂度为O(logM∗1003 )。
Code
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define ll long longusing namespace std;const ll maxn=105,mo=998244353;ll n,i,t,j,k,l,m,p,q,x,f[maxn][maxn],g[maxn],g1[maxn],c1[maxn];ll ans,d[maxn];ll mi(ll x,int y){ if (y==1) return x; if (!y) return 1; ll t=mi(x,y/2); if (y%2) return t*t%mo*x%mo;return t*t%mo;}ll c(ll x,ll y){ return c1[x]*mi(c1[y]*c1[x-y]%mo,mo-2)%mo;}struct code{ ll a[maxn][maxn]; code friend operator * (code x,code y){ code z;memset(z.a,0,sizeof(z.a));int i,j,k; for (i=1;i<maxn;i++) for (j=1;j<maxn;j++) for (k=1;k<maxn;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mo)%mo; return z; }}f1,f2,b;void mi1(int y){ while (y>1) d[++d[0]]=y%2,y/=2; b=f1; for (i=d[0];i>=1;i--){ b=b*b; if (d[i]) b=b*f1; }}int main(){ //freopen("data.in","r",stdin);// freopen("color.in","r",stdin);freopen("color.out","w",stdout); scanf("%d%d%d%d",&n,&m,&p,&q); c1[0]=1; for (i=1;i<maxn;i++) c1[i]=c1[i-1]*i%mo; f[0][0]=1; for (i=1;i<=n;i++) for (j=1;j<=min(i,p);j++) f[i][j]=(f[i-1][j-1]*(p-(j-1))%mo+f[i-1][j]*j%mo)%mo; for (j=1;j<=p;j++) f2.a[1][j]=g[j]=f[n][j],g1[j]=(g[j]*mi(c(p,j),mo-2))%mo; for (j=1;j<=p;j++) for (k=1;k<=p;k++){ for (x=max(j,max(k,q));x<=min(j+k,p);x++) f1.a[j][k]=(f1.a[j][k]+c(j,j+k-x)%mo*c(p-j,x-j)%mo)%mo; f1.a[j][k]=f1.a[j][k]*g1[k]%mo; } if (m>1) mi1(m-1),f2=f2*b; for (i=1;i<=p;i++) ans=(ans+f2.a[1][i])%mo; printf("%lld\n",ans);}
2 0
- JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏
- 【NOIP2016提高A组集训第9场11.7】涂色游戏
- jzoj 4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏 动态规划+排列组合+矩阵乘法
- 【NOIP2016提高A组集训第9场11.7】Simple
- 【NOIP2016提高A组集训第9场11.7】平均数
- NOIP2016提高A组集训第9场11.7总结
- JZOJ4868. 【NOIP2016提高A组集训第9场11.7】Simple
- JZOJ4869【NOIP2016提高A组集训第9场11.7】平均数
- 【JZOJ4868】【NOIP2016提高A组集训第9场11.7】Simple
- 【JZOJ4869】【NOIP2016提高A组集训第9场11.7】平均数
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
- NOIP2016提高A组集训第1场 【JZOJ4824】配对游戏
- 【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ 4824. 【NOIP2016提高A组集训第1场10.29】配对游戏
- 【NOIP2016提高A组集训第2场10.30】钻石游戏
- 【NOIP2016提高A组集训第3场10.31】方程式
- 【NOIP2016提高A组集训第5场11.2】夕阳
- 方程式 【NOIP2016提高A组集训第3场10.31】
- Android ShellUtils-Shell相关工具类
- 2. 有关工厂的几个模式(二) 抽象工厂
- Matalb图形修饰命令函数
- convolution层特点及有无激活函数(caffe)
- Activity常用控件
- JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏
- 51nod 1105 第K大的数
- Serializable的作用
- 1135: [POI2009]Lyz
- sqlite数据库及常用命令
- JAVA之基础(个人学习总结)
- C 任意进制转换程序
- 解决 Centos7 下中文显示乱码
- 【hdu 3336】Count the string(kmp)