Peaks

求n个排列中有恰好k个峰的方案数,模239

n<=1015,k<=30

题解

\(f(i,j)\) 表示填了 \(1~ i\) 有 \(j\) 个峰的方案数。

那么 \(2j\cdot f(i,j) \rightarrow f(i+1,j)\),\((i+1-2j)\cdot f(i,j) \rightarrow f(i+1,j+1)\)。

于是转移可以写成矩阵形式。考虑系数 \(i+1-2j\) 怎么处理。发现由于模数很小,所以可以利用矩阵的周期性。

k和模数的大小提示找规律,事实上当 \(k\leq 30\) 时,\(f(n,k)=f(n+56882,k)~(\bmod 239)\)

CO int mod=239;
int f[56882][31]; int main(){
int n=read<LL>()%56882,k=read<int>();
f[1][1]=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=k;++j)if(f[i][j]){
f[i+1][j]=(f[i+1][j]+2*j*f[i][j])%mod;
f[i+1][j+1]=(f[i+1][j+1]+(i+1-2*j)*f[i][j])%mod;
}
printf("%d\n",f[n][k]);
return 0;
}

3401 石头游戏 0x30「数学知识」例题

描述

石头游戏在一个 n 行 m 列 (1≤n,m≤8) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数字指明。
操作序列是一个长度不超过6且循环执行、每秒执行一个字符的字符串。每秒钟,所有格子同时执行各自操作序列里的下一个字符。序列中的每个字符是以下格式之一:
  • 数字0~9:表示拿0~9个石头到该格子。
  • NWSE:表示把这个格子内所有的石头推到相邻的格子,N表示上方,W表示左方,S表示下方,E表示右方。
  • D:表示拿走这个格子的所有石头。
给定每种操作序列对应的字符串,以及网格中每个格子对应的操作序列,求石头游戏进行了 t 秒之后,石头最多的格子里有多少个石头。在游戏开始时,网格是空的。

输入格式

第一行4个整数n, m, t, act。

接下来n行,每行m个字符,表示每个格子对应的操作序列。

最后act行,每行一个字符串,表示从0开始的每个操作序列。

输出格式

一个整数:游戏进行了t秒之后,所有方格中最多的格子有多少个石头。

样例输入

1 6 10 3
011112
1E
E
0

样例输出

3

样例解释

这是另一个类似于传送带的结构。左边的设备0间隔地产生石头并向东传送。设备1向右传送,直到设备2。10秒后,总共产生了5个石头,2个在传送带上,3个在最右边。

分析

由于\(\le 6\)的正整数的公倍数是60,所以每60秒操作序列一定会循环。那么考虑矩阵转移,预处理每秒转移矩阵和60秒的转移矩阵乘积,对\(\lfloor \frac{t}{60} \rfloor\)做60秒的,\(t \bmod 60\)做单秒的。为了新增石头,增加一个节点来提供。

时间复杂度\(O(60^3(\log \lfloor \frac{t}{60} \rfloor+t \bmod 60))\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll; ll f[70],d[70][70],e[70][70][70];
char b[20][20],s[100];
int n,m,t,act,p,a[20][20],c[20][20];
int num(int i,int j){
return (i-1)*m+j;
}
void mulself(ll a[70][70],ll b[70][70]){
static ll w[70][70];
memset(w,0,sizeof w);
for(int i=1;i<=p;++i)
for(int k=1;k<=p;++k) if(a[i][k])
for(int j=1;j<=p;++j)
w[i][j]+=a[i][k]*b[k][j];
memcpy(a,w,sizeof w);
}
void mul(ll a[70],ll b[70][70]){
static ll w[70];
memset(w,0,sizeof w);
for(int i=1;i<=p;++i)
for(int j=1;j<=p;++j)
w[i]+=a[j]*b[j][i];
memcpy(a,w,sizeof w);
}
int main(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
read(n),read(m),read(t),read(act);
for(int i=1;i<=n;++i){
scanf("%s",s+1);
for(int j=1;j<=m;++j) a[i][j]=s[j]-'0'+1;
}
for(int i=1;i<=act;++i) scanf("%s",b[i]);
p=n*m+1;
for(int k=1;k<=60;++k){
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
int x=a[i][j],y=c[i][j];
if(isdigit(b[x][y])){
e[k][p][num(i,j)]=b[x][y]-'0';
e[k][num(i,j)][num(i,j)]=1;
}
else if(b[x][y]=='N'&&i>1) e[k][num(i,j)][num(i-1,j)]=1;
else if(b[x][y]=='W'&&j>1) e[k][num(i,j)][num(i,j-1)]=1;
else if(b[x][y]=='S'&&i<n) e[k][num(i,j)][num(i+1,j)]=1;
else if(b[x][y]=='E'&&j<m) e[k][num(i,j)][num(i,j+1)]=1;
c[i][j]=(y+1)%strlen(b[x]);
}
e[k][p][p]=1;
}
memcpy(d,e[1],sizeof e[1]);
for(int k=2;k<=60;++k) mulself(d,e[k]);
f[p]=1;
for(int w=t/60;w;w>>=1){
if(w&1) mul(f,d);
mulself(d,d);
}
for(int w=t%60,i=1;i<=w;++i) mul(f,e[i]);
ll ans=0;
for(int i=1;i<p;++i) ans=std::max(ans,f[i]);
printf("%lld\n",ans);
return 0;
}

CH3401 石头游戏的更多相关文章

  1. CH3401 石头游戏(矩阵快速幂加速递推)

    题目链接:传送门 题目: 石头游戏 0x30「数学知识」例题 描述 石头游戏在一个 n 行 m 列 (≤n,m≤) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数 ...

  2. 【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)

    [BZOJ2000][HNOI2000]取石头游戏(贪心,博弈论) 题面 BZOJ 洛谷 题解 这题好神仙啊,窝不会QaQ. 假装一下只有三个元素\(a_{i-1},a_i,a_{i+1}\),并且满 ...

  3. CH 3401 - 石头游戏 - [矩阵快速幂加速递推]

    题目链接:传送门 描述石头游戏在一个 $n$ 行 $m$ 列 ($1 \le n,m \le 8$) 的网格上进行,每个格子对应一种操作序列,操作序列至多有 $10$ 种,分别用 $0 \sim 9$ ...

  4. 【BZOJ2973】石头游戏 矩阵乘法

    [BZOJ2973]石头游戏 Description 石头游戏的规则是这样的. 石头游戏在一个n行m列的方格阵上进行.每个格子对应了一个编号在0~9之间的操作序列. 操作序列是一个长度不超过6且循环执 ...

  5. [luogu] P3210 [HNOI2010]取石头游戏(贪心)

    P3210 [HNOI2010]取石头游戏 题目描述 A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参 ...

  6. 7月18日刷题记录 二分答案跳石头游戏Getting

    通过数:1 明天就要暑假编程集训啦~莫名开心 今天做出了一道 二分答案题(好艰辛鸭) 1049: B13-二分-跳石头游戏(二分答案) 时间限制: 5 Sec  内存限制: 256 MB提交: 30  ...

  7. 牛客1024B 石头游戏

    题目描述 石头游戏在一个 \(n\) 行 \(m\) 列 \((1\leq n,m \leq 8)(1≤n,m≤8)\) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这1 ...

  8. AcWing 206. 石头游戏 矩阵乘法|矩阵快速幂

    AcWing 206. 石头游戏 石头游戏在一个 n 行 m 列 (1≤n,m≤8) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数字指明. 操作序列是一个长度不 ...

  9. JAVA-小青蛙跳石头游戏

    游戏摘自微信传的手机网页版小游戏,我拿来做成了JAVA的界面版,但是没有去做素材,,直接拿方块代替小青蛙.游戏原址就不分享了,只能在手机上打开. 下面是源码: /* * Main.java * */ ...

随机推荐

  1. in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

    最近在用ruby的一些库的时候,总是出现这个错误. 在使用net/imap库的时候,或者net/http库(主要是用到了https,https是用了ssl) 的时候,具体如下: 错误提示:E:/Rub ...

  2. HTML格式布局

    一.position:fixed 锁定位置(相对于浏览器的位置),例如有些网站的右下角的弹出窗口. #top { border:1px solid #; height:100px; width:966 ...

  3. hdu5106 数位dp

    这题说的是给了一个二进制数R , 计算出 在[0,R) 区间内的数, 二进制中有n个1 个和 n<=1000; R<2^1000, 这样 用dp[len][lee] 表示在第len位的时候 ...

  4. SQL case when 多条件查询

    基于列的逻辑表达式,其实就是CASE表达式.可以用在SELECT,UPDATE,DELETE,SET以及IN,WHERE,ORDER BY和HAVING子句之后.下面给个简单示例:

  5. iptables命令、规则、参数详解

    表    (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...

  6. 20145122《Java程序设计》第一周学习总结

    这周的JAVA学习开始了. 首先我了解JVM.JRE与JDK的区别与联系.JDK : (Java开发工具包).JDK是整个Java的核心,包括了Java运行环境JRE.Java工具和Java基础类库等 ...

  7. 20145221 《Java程序设计》第十周学习总结

    20145221 <Java程序设计>第十周学习总结 网络编程 网络概述 概述 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出现,所以在实际的开发中网 ...

  8. HeyWeGo小组团队项目管理

    HeyWeGo团队小组项目管理 项目内容 使用java程序开发一款扫雷游戏 实现计划 第一周 明确项目内容.目标.分工,以及完成前期的一些准备 建立新的小组博客以及创建新的代码托管链接 第二周 实行初 ...

  9. What's the difference between SDK and Runtime in .NET Core?

    What's the difference between SDK and Runtime in .NET Core? Answer1 According to the .Net Core Guide ...

  10. 【转载】Java关键字之"transient"

    原文出处:http://blog.csdn.net/lanxuezaipiao/article/details/16358677 transient的作用及使用方法 我们都知道一个对象只要实现了Ser ...