[xsy2880]取石子游戏
题意:有$n$堆石子,每堆石子数量相同,以质因数分解给出,不停地从$1$到$n$依次拿石子,使得取完后石子个数为原来的因数(不能不取),当一堆只剩$1$个时结束,问在每堆石子结束的方案数
记石子个数为$\prod\limits_{i=1}^mp_i^{e_i}$,拿石头就是选一些$e_i$把它们减小
令一堆石子取$x$次取完的方案数为$f_x$,取$x-1$次还未取完的方案数为$g_x$,那么$g_x=f_x$,因为对于每个取$x-1$次未取完的方案,把它取完就对应一个$x$次取完的方案,对于每个$x$次取完的方案,它的前$x-1$次操作一定不完全相同,所以两种方案数相同
记$s=\sum e_i$,那么取$j$次取完并在$i$结束的方案数为$g_{j+1}^{i-1}f_jg_j^{n-i}=f_{j+1}^{i-1}f_j^{n-i+1}$,所以答案为$ans_i=\sum\limits_{j=1}^sf_{j+1}^{i-1}f_j^{n-i+1}$
现在我们来算$f$,直接算将$e_i$分成$x$份的方案数就是$h_x=\prod\limits_{i=1}^m\binom{e_i+x-1}{x-1}$,但$h_x\ne f_x$,因为$h_x$中可能包含那些某一次一个石子都没取的方案,所以要容斥
取$x$次中,至少有$y$次一个石子都没取的方案数为$\binom xyh_{x-y}$,那么$f_x=\sum\limits_{y=0}^x(-1)^y\binom xyh_{x-y}$,也就是说求出$h$后我们就可以$O(s\log s)$求$f$了
原题中$h$可以暴力求,但毒瘤代爷稍微加强了一下数据,注意到因为$\sum e_i=s$,所以不同的$e_i$最多会有$O(\sqrt s)$个,所以我们对相同的$e_i$一起处理,就可以在$O(s\sqrt s\log s)$的时间内递推求得$h$
总时间复杂度$O(s\sqrt s\log s)$
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=998244353;
int mul(int a,int b){return(ll)a*b%mod;}
int ad(int a,int b){return(a+b)%mod;}
int de(int a,int b){return(a-b)%mod;}
void inc(int&a,int b){(a+=b)%=mod;}
int pow(int a,int b){
int s=1;
while(b){
if(b&1)s=mul(s,a);
a=mul(a,a);
b>>=1;
}
return s;
}
int rev[1048576],N,iN;
void pre(int n){
int i,k=0;
for(N=1,k=0;N<=n;N<<=1)k++;
for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
iN=pow(N,mod-2);
}
void ntt(int*a,int on){
int i,j,k,t,w,wn;
for(i=0;i<N;i++){
if(i<rev[i])swap(a[i],a[rev[i]]);
}
for(i=2;i<=N;i<<=1){
wn=pow(3,on==1?(mod-1)/i:mod-1-(mod-1)/i);
for(j=0;j<N;j+=i){
w=1;
for(k=0;k<i>>1;k++){
t=mul(a[i/2+j+k],w);
a[i/2+j+k]=de(a[j+k],t);
a[j+k]=ad(a[j+k],t);
w=mul(w,wn);
}
}
}
if(on==-1){
for(i=0;i<N;i++)a[i]=mul(a[i],iN);
}
}
int e[10010],inv[300010],fac[300010],rfac[300010],h[300010],f[300010],c[300010],pe[300010],pc[300010];
int C(int n,int k){return mul(fac[n],mul(rfac[k],rfac[n-k]));}
int a[1048576],b[1048576];
int main(){
int m,n,s,i,j,t,M;
scanf("%d%d",&m,&n);
s=0;
for(i=1;i<=m;i++){
scanf("%d%d",&t,e+i);
s+=e[i];
c[e[i]]++;
}
M=0;
for(i=1;i<=s;i++){
if(c[i]){
M++;
pe[M]=i;
pc[M]=c[i];
}
}
fac[0]=1;
for(i=1;i<=s;i++)fac[i]=mul(fac[i-1],i);
rfac[s]=pow(fac[s],mod-2);
for(i=s;i>0;i--)rfac[i-1]=mul(rfac[i],i);
inv[1]=1;
for(i=2;i<=s;i++)inv[i]=-mul(mod/i,inv[mod%i]);
h[1]=1;
for(i=1;i<s;i++){
h[i+1]=h[i];
for(j=1;j<=M;j++)h[i+1]=mul(h[i+1],pow(mul(pe[j]+i,inv[i]),pc[j]));
}
pre(s<<1);
for(i=0;i<=s;i++){
a[i]=(i&1?-1:1)*rfac[i];
b[i]=mul(h[i],rfac[i]);
}
ntt(a,1);
ntt(b,1);
for(i=0;i<N;i++)a[i]=mul(a[i],b[i]);
ntt(a,-1);
for(i=0;i<=s;i++)f[i]=mul(a[i],fac[i]);
for(i=1;i<=n;i++){
t=0;
for(j=1;j<=s;j++)inc(t,mul(pow(f[j+1],i-1),pow(f[j],n-i+1)));
inc(t,mod);
printf("%d\n",t);
}
}
[xsy2880]取石子游戏的更多相关文章
- Games:取石子游戏(POJ 1067)
取石子游戏 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37662 Accepted: 12594 Descripti ...
- HDU 2516 取石子游戏(斐波那契博弈)
取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- hdu 1527 取石子游戏(Wythoff Game)
题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...
- HDU 2516 取石子游戏(FIB博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ
Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...
- HDU-1527 取石子游戏
http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换 :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...
- bzoj 1874 取石子游戏 题解 & SG函数初探
[原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 334 Solved ...
- HDU 2516 取石子游戏 (博弈论)
取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出" ...
- 【POJ】1067 取石子游戏(博弈论)
Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
随机推荐
- CSUST选拔赛题解
本鶸鸡于本月10号参加了蔽校的选拔赛,成绩差的死,大部分的题都是赛后花了好长时间才补出来的,其中有些题还是靠QAQorz大佬帮忙才能解决,感谢Qls对我的帮助~接下来就附带上我的暴力题解,大佬们有更好 ...
- HTML跳转新窗口的方法
笔试遇到这样的一个问题,特意整理一下. 方法一 纯HTML <a href="http://www.cnblogs.com" target="_blank" ...
- hadoop2.4.1伪分布式环境搭建
注意:所有的安装用普通哟用户安装,所以首先使普通用户可以以sudo执行一些命令: 0.虚拟机中前期的网络配置参考: http://www.cnblogs.com/qlqwjy/p/7783253.ht ...
- 如何修改或美化linux终端
先丢一张效果图: 如何让您的 LD 的终端更具个性呢?首先,我们需要了解下面几点知识.A:配置文件 个人配置文件:~/.bashrc全局设定文件:/etc/bash.bashrc(修改需要管理员权限) ...
- 安装FFMpeg CentOS 7
https://linuxadmin.io/install-ffmpeg-on-centos-7/
- 【目录】Python模块学习系列
目录:Python模块学习笔记 1.Python模块学习 - Paramiko - 主机管理 2.Python模块学习 - Fileinput - 读取文件 3.Python模块学习 - Confi ...
- Bit banging
Bit banging Bit banging is a technique for serial communications using software instead of dedicated ...
- 64_g3
gimp-resynthesizer-2.0-6.20160601git787ee5a.fc2..> 11-Feb-2017 05:36 77650 gimp-save-for-web-0.29 ...
- CentOS安装按进程实时统计流量情况工具NetHogs笔记
CentOS安装按进程实时统计流量情况工具NetHogs笔记 一.概述 NetHogs是一款开源.免费的,终端下的网络流量监控工具,它可监控Linux的进程或应用程序的网络流量.NetHogs只能实时 ...
- Python构造函数使用
1. 子类不定义构造函数时候,默认引用父类构造函数 class A(object): def __init__(self,name): self.name = name def run(self): ...