题意:有$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]取石子游戏的更多相关文章

  1. Games:取石子游戏(POJ 1067)

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37662   Accepted: 12594 Descripti ...

  2. HDU 2516 取石子游戏(斐波那契博弈)

    取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  3. hdu 1527 取石子游戏(Wythoff Game)

    题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...

  4. HDU 2516 取石子游戏(FIB博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ

    Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...

  6. HDU-1527 取石子游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换  :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...

  7. bzoj 1874 取石子游戏 题解 &amp; SG函数初探

    [原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved ...

  8. HDU 2516 取石子游戏 (博弈论)

    取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出" ...

  9. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

随机推荐

  1. Morley's Theorem (计算几何基础+向量点积、叉积、旋转、夹角等+两直线的交点)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  2. Centos7的iso everything与DVD以及Live的区别

    DVD.ISO 可以用安装程序安装的所有安装包,推荐镜像 Netinstall.iso 从网络安装或者救援系统 Everything.iso 包含centos7的一套完整的软件包,可以用来安装系统或者 ...

  3. [Leetcode Week12]Unique Paths II

    Unique Paths II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/unique-paths-ii/description/ Descrip ...

  4. openfire在内网的情况下 文件传输代理的设置

    openfire在内网的情况下 文件传输代理的设置 http://blog.csdn.net/v6543210/article/details/22506565

  5. sicily 1063. Who's the Boss

    Time Limit: 1sec    Memory Limit:32MB  Description Several surveys indicate that the taller you are, ...

  6. TensorFlow计算模型—计算图

    TensorFlow是一个通过计算图的形式来表述计算的编程系统.其中的Tnesor,代表它的数据结构,而Flow代表它的计算模型.TensorFlow中的每一个计算都是计算图上的一个节点,而节点之间的 ...

  7. edittext 的一个案例

        <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...

  8. ibatis的动态Mapped Statement 标签

    动态Mapped Statement 直接使用JDBC 一个非常普遍的问题是动态SQL.使用参数值.参数本身和数据列都是动态的SQL,通常非常困难.典型的解决方法是,使用一系列if-else 条件语句 ...

  9. string char * const char *之间的互相转换

    string  ->   const char * 用str的c_str()方法或者data()方法均可,这个两个方法返回值为cong char * string str = "hel ...

  10. 对angular.js的一点理解

    最近一直在学习angular.js.不得不说和jquery相比有很大不同,有很多的不同点,之前也用过Knockout.js 但是两者还是有一定的区别的,首先knockout.js是基于Mvvm的,是几 ...