LYDSY模拟赛day3 涂色游戏



/*
非常好的题
*/
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int N=,mod=;
int c[N][N],s[N][N],f[N][N];
struct mat{
int a[N][N];
}ans,tmp;
int p;
mat operator*(mat a,mat b){
int i,j,k;mat c;
for(i=;i<=p;i++)
for(j=;j<=p;j++){
c.a[i][j]=;
for(k=;k<=p;k++) c.a[i][j]=(c.a[i][j]+(ll)a.a[i][k]*b.a[k][j])%mod;
}
return c;
}
int ksm(int x,int y){
int tmp=x,ans=;
while(y){
if(y&) ans=(ll)ans*tmp%mod;
tmp=(ll)tmp*tmp%mod;
y>>=;
}
return ans;
}
int main(){
//freopen("color.in","r",stdin);
//freopen("color.out","w",stdout);
int n,m,q,i,j,k,x,sum=;
scanf("%d %d %d %d",&n,&m,&p,&q);
c[][]=;//组合数
for(i=;i<=p;i++){
c[i][]=c[i][i]=;
for(j=;j<i;j++)
c[i][j]=(c[i-][j-]+c[i-][j])%mod;//求组合数的过程
}
f[][]=;//i个格子恰好涂j种颜色的方案数
for(i=;i<=n;i++)
for(j=;j<=p;j++)
f[i][j]=((ll)f[i-][j-]*(p-j+)+(ll)f[i-][j]*j)%mod;//分两类讨论,前i-1个格子中使用j-1种颜色而这一格新增一种颜色,前i-1个格子使用j种颜色,这一格涂的颜色在这j种颜色之中
/*
tmp就是题解中所提到的转移函数,a[i][j]就是前一列涂了i个颜色而下一列涂了j个颜色的方案
我们之前已经处理出了i个格子j种颜色的方案数,注意这个方案数是不限制颜色的,也就是说这个j种颜色具体是什么不确定,要想把他确定下来,必须要除c(p,j)(排列组合原理)
考虑两行之间的转移,相邻两个格子分别用了j,k种颜色,两种颜色根据并的颜色的不同会产生不同的结果,枚举这个并的颜色的数量,下界在必须颜色数和两个集合颜色的种数中选取最大值,上界在两集合颜色总数和总共可使用的颜色中取最小值
并的颜色和不同的颜色分别用排列组合算数量再根据乘法原理合起来,最后乘以前一行确定颜色的方案数(确定颜色后方案之间是等价的)
*/
for(j=;j<=p;j++)
for(k=;k<=p;k++){
for(x=max(q,max(j,k));x<=min(j+k,p);x++)
tmp.a[j][k]=(tmp.a[j][k]+(ll)c[j][j+k-x]*c[p-j][x-j])%mod;
tmp.a[j][k]=(ll)f[n][k]*tmp.a[j][k]%mod*ksm(c[p][k],mod-)%mod;
//printf("%d ",tmp.a[j][k]);
}
m--;
for(i=;i<=p;i++) ans.a[i][i]=;//单位矩阵
//假设转移两遍,a[i][j] = sum(a[i][k]*a[k][j])(1<=i,j<=p)符合矩阵乘法的形式,所以可以用矩阵快速幂
while(m){
if(m&) ans=ans*tmp;
tmp=tmp*tmp;m>>=;
}
for(i=;i<=p;i++)
for(j=;j<=p;j++)
sum=(sum+(ll)f[n][i]*ans.a[i][j])%mod;//转移
printf("%d\n",sum);
return ;
}
LYDSY模拟赛day3 涂色游戏的更多相关文章
- 联赛模拟测试5 涂色游戏 矩阵优化DP
题目描述 分析 定义出\(dp[i][j]\)为第\(i\)列涂\(j\)种颜色的方案数 然后我们要解决几个问题 首先是求出某一列涂恰好\(i\)种颜色的方案数\(d[i]\) 如果没有限制必须涂\( ...
- LYDSY模拟赛day3 序列
NOIP不考可持久,弃坑
- LYDSY模拟赛day3 平均数
[ 问题描述]有一天, 小 A 得到了一个长度为 n 的序列.他把这个序列的所有连续子序列都列了出来, 并对每一个子序列都求了其平均值, 然后他把这些平均值写在纸上, 并对它们进行排序,最后他报出了第 ...
- [CSP-S模拟测试]:涂色游戏(DP+组合数+矩阵快速幂)
题目描述 小$A$和小$B$在做游戏.他们找到了一个$n$行$m$列呈网格状的画板.小$A$拿出了$p$支不同颜色的画笔,开始在上面涂色.看到小$A$涂好的画板,小$B$觉得颜色太单调了,于是把画板擦 ...
- hdu 4559 涂色游戏(SG)
在一个2*N的格子上,Alice和Bob又开始了新游戏之旅. 这些格子中的一些已经被涂过色,Alice和Bob轮流在这些格子里进行涂色操作,使用两种涂色工具,第一种可以涂色任意一个格子,第二种可以涂色 ...
- NOIp十连测 涂色游戏
[问题描述]小A 和小B 在做游戏.他们找到了一个n 行m 列呈网格状的画板.小A 拿出了p 支不同颜色的画笔,开始在上面涂色.看到小A 涂好的画板,小B 觉得颜色太单调了,于是把画板擦干净,希望涂上 ...
- hdu 4559 涂色游戏(对SG函数的深入理解,推导打SG表)
提议分析: 1 <= N <= 4747 很明显应该不会有规律的,打表发现真没有 按题意应该分成两种情况考虑,然后求其异或(SG函数性质) (1)找出单独的一个(一列中只有一个) (2)找 ...
- 【2018.10.20】noip模拟赛Day3 飞行时间
今天模拟赛题目 纯考输入的傻逼题,用$scanf$用到思想僵化的我最终成功被$if$大法爆$0$了(这题只有一组$100$分数据). 输入后面那个$(+1/2)$很难$if$判断,所以我们要判两个字符 ...
- LYDSY模拟赛day9 2048
/* 大模拟题,做的时候思路还是比较清晰的 */ #include<iostream> #include<cstdio> #include<string> #inc ...
随机推荐
- Bzoj2118 墨墨的等式
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1488 Solved: 578 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+ ...
- AC 自动机
AC自动机(Aho-Corasick Automata)是经典的多模式匹配算法.从前我学过这个算法,但理解的不深刻,现在已经十分不明了了.现在发觉自己对大部分算法的掌握都有问题,决定重写一系列博客把学 ...
- FZU 1752 A^B mod C(快速加、快速幂)
题目链接: 传送门 A^B mod C Time Limit: 1000MS Memory Limit: 65536K 思路 快速加和快速幂同时运用,在快速加的时候由于取模耗费不少时间TLE了 ...
- 【Alpha版本】冲刺-Day8
队伍:606notconnected 会议时间:11月16日 会议总结 张斯巍(433) 今天安排:回收站界面设计 完成度:90% 明天计划:关注界面设计 遇到的问题:无 感想:有时候自己设计的队友说 ...
- Untiy3D - 窗口界面1
记录Untiy3D学习中的英语单词 一.Project窗口下的英语单词 First Day Folder : 文件夹 C# Script : C#脚本 JavaScript:JS脚本 Editor T ...
- zoj 3946 Highway Project(最短路 + 优先队列)
Highway Project Time Limit: 2 Seconds Memory Limit: 65536 KB Edward, the emperor of the Marjar ...
- Java 性能优化技巧集锦
摘要: =================================== 可供程序利用的资源(内存.CPU时间.网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务.优化通常 ...
- 闭包->类的实例数组排序
简单的字符串数组排序就一句话 Arr.sort(function(s1,s2){return s1.localeCompare(s2));//升序 Arr.sort(function(s1,s2){r ...
- Java递归算法——三角数字
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- javascript字符串截取的substring、substr和slice
本文详细的介绍了javascript中substring().substr()和slice()三个JS字符串截取的方法,substring()方法用于提取字符串中介于两个指定下标之间的字符.subst ...