Description

Data Constraint

Solution

我们设f[i][j]表示当前有i个格子恰好放了j种颜色的方案数,那么f[i][j]=f[i−1][j−1]∗(p−(j−1))+f[i−1][j]∗jf[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−jf1[j][k]={g[j]\over{C^{j}_{p}}}*\sum^{min(j+k,p)}_{x=max(q,j,k)}{C^{j+k-x}_{j}*C^{x-j}_{p-j}}。

解释一下:我们刚开始讲的g[j]包含的是p中任意j种颜色以任意顺序放入n个格子的方案数,那么对于p中任意j种颜色的方案数都是相等的,即g[j]Cjp{g[j]\over{C^{j}_{p}}}。明显对于j,k,它们的并集x最大是j+k,但由于最多只有p种颜色,所以x的上限为min(j+k,p)min(j+k,p),同时,x必须必j和k都大,由于题目要求交集必须大于q,所以x的下限为max(j,k,q)max(j,k,q)。现在要求出k的颜色的组成,为了不重复不遗漏,我们对是否在j和k的交集的颜色分别求Cj+k−xjC^{j+k-x}_{j}表示j和k的交集有多少种情况(即在j中选出j和k的交集)。Cx−jp−jC^{x-j}_{p-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]f2[1][k]=g[k],f2[i][k]=\sum^{p}_{j=1}{f2[i-1][k]*f1[j][k]}。打一下矩阵乘法即可,时间复杂度为O(logM∗1003logM*100^3)。

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using 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);
}

JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏相关推荐

  1. 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块

    题目描述 Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者之一.其中,冰 ...

  2. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  3. JZOJ4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰 2017.10(B组)

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  4. 【JZOJ4884】【NOIP2016提高A组集训第12场11.10】图的半径

    题目描述 mhy12345学习了树的直径,于是开始研究图的半径,具体来说,我们需要在图中选定一个地方作为中心,其中这个中心有可能在路径上. 而这个中心的选址需要能够使得所有节点达到这个中心的最短路里面 ...

  5. JZOJ4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目 20 40 80 100 大致流程 code 题目 Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核 ...

  6. jzoj 4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  7. 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目描述 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取一些原子,排成 ...

  8. 【JZOJ4896】【NOIP2016提高A组集训第16场11.15】兔子

    题目描述 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝之 ...

  9. 【NOIP2016提高A组集训第7场11.4】推冰块

    Description Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者 ...

最新文章

  1. Apache配置代理服务器的方法(2)
  2. sklearn分类模型
  3. 梦幻西游服务器每周几维护,梦幻西游5月6日维护公告:唯美版地图不再更新
  4. Vue 项目调试总结
  5. 61 MM配置-后勤发票校验-发票冻结-设置容差限制
  6. 处理兼容问题:对于某些css3属性需要加前缀?
  7. Oracle下载 OPatch
  8. 360浏览器清凉新版让手机解暑
  9. MVC路由 路由的三种扩展 替换MVC内置的Handler
  10. [转]CellCtrl控件完美破解研究
  11. module.exports 和 exports 的区别
  12. VS2013 Codejock 实现 MFC 换肤
  13. 小米推送,华为推送,个推,阿里云推送集成(服务端JAVA开发)
  14. 侯晓迪:全身心的投入,吃住都在实验室
  15. keil编译出现多重定义的问题
  16. 装linux双系统有什么好处,科学网—Windows和Linux双系统安装教程 - 戴劭勍的博文...
  17. 计算机显示器型号参数单价,飞利浦电脑显示器价格表一览【详解】
  18. 基于Unity的2D像素风闯关游戏Demo——SunnyLand
  19. ctab提取dna流程图_CTAB法提取植物DNA原理以及步骤
  20. kafka的offset是个什么鬼。。

热门文章

  1. 傲游首页下载次数分析
  2. 【python笔记九】字典创建、字典增删改查、字典常用操作
  3. 嵌入式audio基础(一)接口
  4. 访问ftp不成功的原因以及学习搭建FTP心得
  5. Cloze Test Helps: Effective Video Anomaly Detection via Learning to Complete Video Events 速读整理
  6. 打印全年日历 java实现
  7. 坦桑尼亚签证办理攻略
  8. Redis 6.2 执行hset 操作(源码)
  9. POI 控制 excel 生成图表的方式(一)
  10. 实用Python是如何爬取英雄联盟(lol)全部皮肤,涨知识了