zoukankan      html  css  js  c++  java
  • P4714 「数学」约数个数和

    题目求的东西可以转化为:

    给你一个数,每次把它变成它的一个约数,重复k次,求方案数。(中间过程有一步不同则视为不同)

    这个东西显然可以dp,但是n,k<=1e18。

    考虑每个质因子分别算,就又转化为一个新的问题,给你一个数,每次可以把它变成一个<=它的数字,重复k次。求方案数。(中间过程有一步不同则视为不同)

    这个可以直接插板法来算。设x=π pi^ti,则ans=πC(ti+1+k-1,ti)。

    这里的组合数,虽然n是1e18级别的,但m的取值<=60,可以直接组合数横向递推来求。

    然而我又自闭了,写了一个矩阵乘法优化dp来算qwq。

    最后注意对n分解质因数要用pollard_rho。

    #include<bits/stdc++.h>
    #define M 70
    #define N 110000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    using namespace std;
    inline ll read()
    {
    	char ch=0;
    	ll x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*flag;
    }
    const ll mo=998244353;
    ll rd(ll p){return rand()%p*rand()%p*rand()%p*rand()%p;}
    ll ksc(ll x,ll y,ll p){return ((x*y-(ll)(((ldb)x*y+0.5)/p)*p)%p+p)%p;}
    ll ksm(ll x,ll k,ll p){ll ans=1;while(k){if(k&1)ans=ksc(ans,x,p);k>>=1;x=ksc(x,x,p);}return ans;}
    ll prime[N]={0,2,3,5,7,11,13,17,19,23};
    bool miller_rabin(ll p)
    {
    	if(p<=1)return false;
    	ll k=0,t=p-1;while(!(t&1))t>>=1,k++;
    	for(ll i=1;i<=9;i++)
    	{
    		if(p==prime[i])return true;
    		if(p%prime[i]==0)return false;
    	}
    	for(ll i=1;i<=9;i++)
    	{
    		ll x=ksm(prime[i],t,p),last;
    		for(ll j=1;j<=k;j++)
    		{
    			last=x;x=ksc(x,x,p);
    			if(x==1&&(last!=1&&last!=p-1))
    			return false;
    		}
    		if(x!=1)return false;
    	}
    	return true;
    }
    set<ll>S;
    set<ll>::iterator it;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll find(ll n)
    {
        ll k=2,x=rd(n-1)+1,y=x,d=1,c=rd(n-1)+1;
        for(ll i=1;d==1;i++)
        {
            x=(ksc(x,x,n)+c)%n;
    		d=gcd(abs(x-y),n);
    		if(i==k)k<<=1,y=x;
    	}
        return d;
    }
    void pollard_rho(ll n)
    {
    	if(n==1)return;
        if(miller_rabin(n))return (void)S.insert(n);
        ll t=n;
        while(t==n)t=find(n);
        pollard_rho(t);pollard_rho(n/t);
    }
    ll size;
    struct matrix
    {
    	ll s[M][M];
    	void clear(){memset(s,0,sizeof(s));}
    }f,g;
    matrix operator*(matrix a,matrix b)
    {
    	matrix ans;ans.clear();
    	for(ll i=0;i<=size;i++)for(ll j=0;j<=size;j++)for(ll k=0;k<=size;k++)
        ans.s[i][j]=(ans.s[i][j]+(1ll*a.s[i][k]*b.s[k][j]%mo))%mo;
        return ans;
    }
    matrix E()
    {
    	matrix ans;ans.clear();
    	for(ll i=0;i<=size;i++)ans.s[i][i]=1;
    	return ans;
    }
    matrix pow(matrix x,ll k)
    {
    	matrix ans=E();
    	while(k)
    	{
    		if(k&1)ans=ans*x;
    		k>>=1;x=x*x; 
    	}
    	return ans;
    }
    int main()
    {
    	srand(time(0));
    	ll n=read(),k=read()+1,ans=1;pollard_rho(n);
    	for(it=S.begin();it!=S.end();it++)
    	{
    		ll x=n,o=*it;size=0;
    		while(x%o==0)x/=o,size++;
    		f.clear();f.s[0][size]=1;g.clear();
    		for(ll i=0;i<=size;i++)for(ll j=0;j<=i;j++)g.s[i][j]=1;
    		f=f*pow(g,k);
    		ll t=0;
    		for(ll i=0;i<=size;i++)t=(t+f.s[0][i])%mo;
    		ans=1ll*ans*t%mo;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python os模块的使用
    数据分析 关于基础组件与介绍
    [SRH.Docker] HBase Java 第一天学习记录
    eclipse创建android项目失败的问题 [ android support library ]
    mysql学习总结
    celery的定时运用
    django认证
    django离线插入测试数据
    关于使用git仓库的操作
    小程序笔记
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10632519.html
Copyright © 2011-2022 走看看