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. HDU 1879 继续畅通工程(Prim||Kruscal模板题)

    原题链接 Prim(点归并) //异或运算:相同为假,不同为真 #include<cstdio> #include<algorithm> #define maxn 105 us ...

  2. 20145202马超 2016-2017-2 《Java程序设计》第8周学习总结

    20145202马超 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 NIO使用频道(channel)来衔接数据节点,对数据区的标 ...

  3. 20145326 《Java程序设计》第10周学习总结

    教材学习内容总结 网络编程 •网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据. •程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴. •在发送 ...

  4. CentOS7.2 安装nginx-1.10.3

    nginx-1.10.3 下载nginx 检查是否安装了依赖库: [root@localhost ~]# rpm -q gcc gcc-4.8.5-11.el7.x86_64 [root@localh ...

  5. Ubuntu16.04 国内更新源

    在修改source.list之前要先备份 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 替换内容到source.list中 阿里云源: ...

  6. 【图片服务器】搭建Nginx图片服务器

    一.安装Nginx 二.安装vsftpd 三.开始搭建Nginx图片服务器 1.效果 例如:图片通过ftp服务上传到/home/ftpuser/www/images目录下,我想通过访问Nginx服务器 ...

  7. Redis之Sorted Set 有序集合

    Redis Sorted Set 有序集合 Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分 ...

  8. 【eclipse】Server Tomcat v9.0 Server at localhost failed to start.

    Server Tomcat v9.0 Server at localhost failed to start. 的一个原因就是启动超时了.

  9. pickle & cPickle ValueError: unsupported pickle protocol: 3

    pickle and cPickle pickle和cPickle是python对象的转储文件,保存的是python对象 他们分别是python2和python3的对应部分,建议引入的时候采用以下方法 ...

  10. python 获取列表的键值对

    nums = [, , , , ] for num_index, num_val in enumerate(nums): print(num_index, num_val)