题解 | #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';
    }
}

全部评论

相关推荐

06-25 21:00
门头沟学院 Java
多拆解背记一下当前的高频场景面试题,结合自己的项目经历去作答,面试通过率原来真的不会低!
牛客96559368...:小公司不就是这样的吗,面试要么是点击就送,要么就是往死里拷打,没有一个统一的标准。这个不能代表所有公司
点赞 评论 收藏
分享
牛客刘北:如果暑期实习是27届的话,你要晚一年才会毕业,企业为什么会等你呢?要搞清时间逻辑呀!27届现在实习只能是在暑假实习,这是日常实习,不是暑期实习。所以多去投日常实习吧,暑期实习肯定不会要你的
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务