【纪中集训2019.3.23】IOer

题目

描述

你要在(m)天内,刷(n)道题,每天可以刷的题的数目不限;

(i)天可以刷的题目的种类是(ui+v)

两种刷题的方案不同当且仅当某天刷题的数量不同或者依次刷题的种类不同;

(T)组询问,每组给出(n,m,u,v);

范围

$1 le T le 5 , 1 le n le 10^{18} , 1 le m le 2 imes 10^5 , 1 le u , v le 10^9 $

题解

  • 典型的数学题,给出两种推导;

  • 首先答案是:

    [egin{align} & sum_{k_1+k_2+cdots + k_m = n} t_1^{k_1} t_2^{k_2} cdots t_m^{k_m} , 其中 t_i = ui+v \ end{align} ]

  • solve 1

    [egin{align} &以下方法的基本思路是利用组合意义推导: \ &Part 1 \ &考虑现在有一些球,这些球上有一个数字1 o m; \ &同时这些球有颜色,其中第i(1<i<m)球标号的球有u种颜色,第m种球有u+v种颜色; \ &两个球相同当且仅当编号和颜色都相同; \ &现在用这些球构成一个n+m-1长度的序列,满足: \ & *编号为1 o m-1的球都出现过,记他们第一次出现的位置为:1 le p_1 , p_2 , cdots , p_{m-1}le n+m-1 \ & *这些球第一次出现的位置满足:1 le p_1 lt p_2 lt p_3 lt cdots lt p_{m-1} le n+m-1 \ &Par 2 \ &先放好p_i , 考虑p_i和p_{i-1}+1中间可以放的球种类是 ui+v , 所以计数这样子的序列是: \ & u^{m-1} sum_{1 lt p_1 lt p_2 lt cdots lt p_{m-1} lt n+m-1 }(u+v)^{p_1-1} (2u+v)^{p_2-p_1-1} (3u+v)^{p_3-p_2-1} cdots (mu+v)^{n+m-1-p_{m-1}-1} \ &前面乘上u^{m-1}是因为p_{1}到p_{m-1}都是u种颜色可选,这样也可以知式子种指数的和是(n+m-1)-(m-1)=n; \ &所以这个式子是答案的u^{m-1}倍,我们只需要计数序列个数除以u^{m-1}即可得到答案;\ &Part 3 \ &进一步前m-1种球都是等价的,所以简化条件成: \ & *编号为1 o m-1的球都出现过; \ &用这个除以(m-1)!即可得到原构造序列的个数; \ &Part 4 \ &利用容斥算出满足简化条件的序列: \ &sum_{S} (-1)^{|S|} (mu + v -|S|u) ^ {n+m-1} \ &=sum_{k=0}^{m-1}(-1)^k (^{m-1}_k) (mu+v-ku)^{n+m-1} \ &综上:答案即是:frac{sum_{k=0}^{m-1}(-1)^k (^{m-1}_k) (mu+v-ku)^{n+m-1}}{(m-1)!u^{m-1}} end{align} ]

  • solve 2

    [egin{align} &以下方法的基本思路是利用生成函数和增量去构造;\ &Part 1 \ &考虑答案即是:[x^n]Pi_{i=1}^{m}frac{1}{1-t_ix}\ &设G(x)=Pi_{i=1}^{m}frac{1}{1-t_ix}\ &假设G(x)有另一种有限项的形式:G(x)=sum_{i=1}^{m}frac{a_i}{1-t_ix}\ &Part 2 \ &尝试用增量法去求出系数a_i,这样我们也同时证明了这种形式的存在;\ &首先明确一个式子:frac{1}{ab}=(frac{1}{a}-frac{1}{b})frac{1}{b-a} &(1) \ &假设现在已经求出了前m-1项乘积的系数a_{m-1,1},cdots,a_{m-1,m-1};\ &考虑乘上一个frac{1}{1-t_mx} ,即:\ &sum_{i=1}^{m-1}frac{a_i}{1-t_ix}frac{1}{1-t_mx} &(2) \ &带入(1),=sum_{i=1}^{m-1}a_i(frac{1}{1-t_ix}-frac{1}{1-t_mx})frac{1}{(i-m)ux} &(3)\ &把ux直接踢出去,最后的G'(x)乘上一个u^{m-1}x^{m-1} \ &所以只考虑sum_{i-1}^{m-1}frac{a_i}{i-m}frac{1}{1-t_ix}+frac{a_i}{m-i}frac{1}{1-t_mx}\ &所以可以得到:\ &a_{i,j}=frac{a_{i-1,j}}{j-i};(j<i)&(4)\ &a_{i,i}=sum_{j=1}^{i-1}frac{a_{i-1,j}}{i-j} &(5)\ &Part 3 \ &为了方便我们设f_i=a_{i,i},(4)可以被进一步写成:a_{i,j}=f_jfrac{(-1)^{i-j}}{(i-j)!} &(6)\ &把(6)带入(5)化简:\ &f_{i}=sum_{j=1}^{i-1}f_jfrac{(-1)^{i-j-1}}{(i-j)!}\ &此时记F(x)为f_{i}的OGF,F(x)=F(x)*(1-e^{-x})+x;\ &解得:F(x)=xe^x;\ &所以f_i=[x^i]F(x)=frac{1}{(i-1)!}; &(7) \ &Part 4\ &接下来就只需要利用(4)和(7)简单化简求答案;\ &ans=[x^n]G(x)\ &=[x^n]frac{G'(x)}{u^{m-1}x^{m-1}} \ &=frac{1}{u^{m-1}}[x^{n+m-1}]G'(x) \ &=frac{1}{u^{m-1}}sum_{k=1}^{m}a_{m,k}t_{k}^{ n+m-1}\ &=frac{1}{u^{m-1}}sum_{k=1}^{m}f_kfrac{(-1)^{m-k}}{(m-k)!}(uk+v)^{n+m-1}\ &=frac{sum_{k=1}^{m}frac{(-1)^{m-k}}{(k-1)!(m-k)!}(uk+v)^{n+m-1}}{u^{m-1}}\ &=frac{sum_{k=0}^{m-1}(-1)^{k}(mu+v-ku)^{n+m-1}}{(m-k-1)!k!u^{m-1}}\ &=frac{sum_{k=0}^{m-1}(-1)^{k}(^{m-1}_k)(mu+v-ku)^{n+m-1}}{(m-1)!u^{m-1}} end{align} ]

  • 两种方法都差不多巧妙只是第二种数学化简比较多所以看起来有点长;

  • 代码就很没意思了->_<-;

    #include<bits/stdc++.h>
    #define ll long long 
    #define mod 998244353
    using namespace std;
    const int N=200010;
    ll n;
    int m,u,v,fac[N];
    int pw(int x,int y){
    	int re=1;
    	while(y){
    		if(y&1)re=(ll)re*x%mod;
    		x=(ll)x*x%mod;y>>=1;
    	}
    	return re;
    }
    int main(){
    	freopen("ioer.in","r",stdin);
    	freopen("ioer.out","w",stdout);
    	int T;cin>>T;
    	for(int i=fac[0]=1;i<=2e5;++i)fac[i]=(ll)fac[i-1]*i%mod;
    	while(T--){
    		cin>>n>>m>>u>>v;
    		int y=(n+m-1)%(mod-1),x=((ll)m*u+v)%mod,c=1,ans=0;
    		for(int i=0;i<=m-1;++i){
    			int now = (ll)c*pw(x,y)%mod;
    			if(i&1)ans=(ans-now+mod)%mod;else ans=(ans+now)%mod;
    			x=(x-u+mod)%mod;
    			c=(ll)(m-i-1)*pw(i+1,mod-2)%mod*c%mod;
    		}
    		ans=1ll*pw(fac[m-1],mod-2)*pw(u,(ll)(mod-2)*(m-1)%(mod-1))%mod*ans%mod;
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
原文地址:https://www.cnblogs.com/Paul-Guderian/p/10590523.html