题解 | #Bash Plays with Functions#

Bash Plays with Functions

https://ac.nowcoder.com/acm/contest/22769/F

提供一篇不使用dp的解法。利用贝尔级数不难证明f0=1+x1x=μ21f_0=\frac{1+x}{1-x}=\mu^2*1,则fr=μ2111r+1=1+x(1x)r+1f_r=\mu^2*\underbrace{1*1*\cdots *1}_{r+1个}=\frac{1+x}{(1-x)^{r+1}}。设g(x)=1(1x)r+1g(x)=\frac{1}{(1-x)^{r+1}},那么有g(x)=i=1s(r+kiki),x=p1k1p2k2psksg(x)=\prod\limits_{i=1}^{s}\tbinom{r+k_i}{k_i},x=p_1^{k_1}p_2^{k_2}\cdots p_s^{k_s},具体证明过程可以在oiwiki的普通生成函数板块找到,剩下的事情就只有求积性函数一类的工作了。

#if __has_include(<bits/stdc++.h>)
#include<bits/stdc++.h>
#endif
#include<iostream>
#include<bitset>
#include<map>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<sstream>
#include<stack>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;
template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){os<<p.first<<" "<<p.second;return os;}
#define debug(x) cerr<<#x<<":"<<x<<endl
#define debug2(x,y) cerr<<#x<<":"<<x<<"  "<<#y<<":"<<y<<endl
#define debug3(x,y,z) cerr<<#x<<":"<<x<<"  "<<#y<<":"<<y<<"  "<<#z<<":"<<z<<endl
#define debuga(a) for(int i=0;i<a.size();++i) debug2(i,a[i]);
#define debugar(a,b) for(int i=0;i<b;++i) debug2(i,a[i]);
using namespace std;
typedef long long ll;
const ll N=1e6+1000,N_=2e6+5000,M=1e9+7;
int cnt=0,prime[N],part[N],prod[N_];
int pfm[N][10],pfmsize[N];
int INV[N_];
void pre(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    INV[0]=INV[1]=part[1]=prod[0]=prod[1]=1;
    for(int i=2;i<N;++i){
        prod[i]=(ll)i*prod[i-1]%M;
        INV[i]=(M-M/i)*INV[M%i]%M;
        if(!part[i]){
            prime[cnt++]=i;
            part[i]=i;
        }
        for(int j=0;i*prime[j]<N;++j){
            part[i*prime[j]]=i%prime[j]?prime[j]:part[i];
            if(i%prime[j]==0) break;
        }
    }
    for(ll i=N;i<N_;++i){
        prod[i]=i*prod[i-1]%M;
        INV[i]=(M-M/i)*INV[M%i]%M;
    }
    for(ll i=2;i<N_;++i) INV[i]=(ll)INV[i]*INV[i-1]%M;
    for(int i=2;i<N;++i){
        ll t=part[i],p=i,c=0;
        while(t!=1){
            p/=part[p];
            ++c;
            if(part[p]!=t){
                pfm[i][pfmsize[i]++]=c;
                t=part[p];
                c=0;
            }
        }
    }
}
ll comb(ll n,ll m){return (ll)prod[m]*INV[n]%M*INV[m-n]%M;}
void foreachp(ll r,ll n,ll ind,ll& res,ll t){
    if(ind==pfmsize[n]){
        res=res+t;
        if(res>=M) res%=M;
        return;
    }
    foreachp(r,n,ind+1,res,t*(comb(pfm[n][ind],r+pfm[n][ind])+comb(pfm[n][ind]-1,r-1+pfm[n][ind]))%M);
}
signed main(){
    pre();
    ll q,r,n;
    cin>>q;
    while(q--){
        cin>>r>>n;
        ll res=0;
        foreachp(r,n,0,res,1);
        cout<<res<<'\n';
    }
}

全部评论

相关推荐

孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务