Problem : 这个题如果不是签到题 Asm.Def就女装(积性函数dp

https://oj.neu.edu.cn/problem/1460

 

思路:若n=(p1^a1)*(p2^a2)...(pn^an),则f(n,0)=a1*a2*...*an,显然f(n,0)是积性函数,对于f(x,y)可以看出他是f(x,y-1)与自身进行狄利克雷卷积得到的结果,所以f(x,y)也是积性函数。因此,只要对n质因子分解,然后预处理出次方的dp值即可。注意积性函数的概念中a,b必须互质!

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1000000007;
const int maxn = 1000000+5,maxm = 10000+5;
int dp[30][maxm];
vector<int> g[maxn];

inline void solve(int n){
    int nn = n;
    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            int num = 0;
            while(n%i==0) n/=i,num++;
            g[nn].push_back(num);
        }
    }
    if(n>1) g[nn].push_back(1);
}

void init(int n=30,int m=maxm){
    for(int i=1;i<n;i++) dp[i][0] = i;
    for(int i=1;i<n;i++){
        for(int j=1;j<m;j++){
            if(i==1){
                dp[i][j] = dp[i][j-1]*2%mod;
            }
            else {
                dp[i][j] = dp[i][j-1]*2%mod;
                for(int k=1;k<i;k++){
                    dp[i][j] = (dp[i][j] + dp[k][j - 1] * dp[i - k][j - 1] % mod) % mod;
                }
            }
        }
    }
}


signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    init();
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        if(n==1) cout<<1<<endl;
        else{
            if(g[n].size()==0) solve(n);
            int ans = 1;
            for(int i=0;i<g[n].size();i++){
                ans = ans*dp[g[n][i]][m]%mod;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

 

posted @ 2019-08-30 13:24  时光已随风而逝~  阅读(129)  评论(0编辑  收藏  举报