洛谷 P4714 「数学」约数个数和

SOL:

  不难发现原题让我们求 k+1个元素之积为n的解的个数。

  我们对每个质因数使用隔板法即可。

#include<bits/stdc++.h>
#define Xx first
#define Yy second
#define LL long long
using namespace std;
LL gcd(LL x,LL y){
    return y?gcd(y,x%y):x;
}
inline LL Get(LL n){
    static LL x=233333333333ll;
    return x^=x<<5,x^=x>>17,x^=x<<13,abs(x)%n;
}
inline LL mul_mod(LL x,LL y,LL mo){
    static LL anw;
    for (anw=0;y;y>>=1,x=(x<<1)%mo)
     if (y&1) anw=(anw+x)%mo;
    return anw;
}
inline LL qsm(LL x,LL y,LL mo){
    static LL anw;
    for (anw=1;y;y>>=1,x=mul_mod(x,x,mo)) if (y&1) anw=mul_mod(anw,x,mo);
    return anw;
}
LL x,y,d;
LL rho(LL n) {
    while (1) {
        LL c=Get(n); 
        int k=2,i=0;
        x=Get(n),y=x;
        x=(mul_mod(x,x,n)+c)%n; 
        while (x^y) {
            if (i==k) {y=x; k<<=1;}
            ++i; 
            x=(mul_mod(x,x,n)+c)%n; 
            d=__gcd(abs(y-x),n);
            if (1<d&&d<n) return d;
        }
    }
}
LL b,t;
LL p[7]={2,3,7,61,24251,13,41};
#define TIM 7
bool MR(LL n) {
    if (n==2||n==3||n==7||n==11||n==13||n==17||n==41) return 1;
    if (n==1||n%2==0||n%3==0||n%7==0||n%11==0||n%13==0||
    n%17==0||n%41==0) return 0;
    if (n==46856248255981) return 0;
    b=n-1; t=0;
    while (!(b&1)) b>>=1,t++;
    for (int tt=0;tt<TIM;tt++) {
        x=qsm(p[tt],b,n);
        for (int i=1;i<=t;i++) {
            y=mul_mod(x,x,n);
            if (y==1&&x!=1&&x!=n-1) return 0;
            x=y;
        }
        if (x!=1) return 0;
    } return 1;
}
map<LL,int> dv;
void Pol_rho(LL dn) {
    if (dn==1) return;
    if (MR(dn)) {
        dv[dn]++; return;}
    LL tmp=rho(dn);
    Pol_rho(tmp); 
    Pol_rho(dn/tmp);
}
LL n,k;
#define pp 998244353
LL get(LL x,int r){
    LL anw=1;
    for (int i=1;i<=r;i++) 
     anw=mul_mod(anw,x-i+1,pp),
     anw=mul_mod(anw,qsm(i,pp-2,pp),pp);
    return anw;
}
LL ans=1;
signed main () {
    scanf("%lld%lld",&n,&k);
    Pol_rho(n);
    for (map<LL,int>::iterator it=dv.begin();it!=dv.end();it++) {
       ans=mul_mod(ans,get(k+it->Yy+1,it->Yy),pp);
    }
    return printf("%lld",ans),0;
}

猜你喜欢

转载自www.cnblogs.com/rrsb/p/9318191.html