zoukankan      html  css  js  c++  java
  • luogu 6月月赛 E 「数学」约数个数和

    题面在这里!

        第一眼感觉炒鸡水啊。。。只要把N质因数分解一下,因为k次约数相当于求k+2元一次方程的非负整数解,所以答案就是和每个质因子指数有关的一些组合数乘起来。

        但是要用pillard's rho啊。。。。

        (于是现学了一下,发现不会Miller Rabin。。。然后又先去学Miller Rabin 23333)

        Miller Rabin 的部分就不说了。。。随便找个博客肯定都讲的比我好多了2333

        Pillard's rho 的原理就是生日悖论,随机s个数之后两两作差并与n求gcd,当s不断增大的时候gcd>1的概率逐渐接近于100%

        问题是怎么随机。。。

        现在普遍在用的方法是 , 先随机一个c,一个x,然后令 y = ( x*x + c ) % n ,求一下gcd(|x-y| , n),如果>1那么返回,否则令x=y。

        但是这么做如果找不到的话会一直循环下去,所以要用一下floyd判环(我写的是倍增判环)。。。

        生成数列a[]的部分都是一样的,只不过是用 | a[now] - a[pre] | 和 n 取gcd 或 判重,其中 pre = 2^i,且i是满足pre<now的极大的i。。。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    #define T 20
    const int ha=998244353;
    
    ll zs[2333],phi,A,ans=1,N;
    int cnt=0;
    
    ll gcd(ll x,ll y){ return y?gcd(y,x%y):x;}
    
    inline ll add(ll x,ll y,const ll ha){ x+=y; return x>=ha?x-ha:x;}
    inline void ADD(ll &x,ll y,const ll ha){ x+=y; if(x>=ha) x-=ha;}
    
    inline ll mul(ll x,ll y,const ll ha){
    	ll an=0;
    	for(;y;y>>=1,ADD(x,x,ha)) if(y&1) ADD(an,x,ha);
    	return an;
    }
    
    inline ll ksm(ll x,ll y,const ll ha){
    	ll an=1;
    	for(;y;y>>=1,x=mul(x,x,ha)) if(y&1) an=mul(an,x,ha);
    	return an;
    }
    
    inline bool Mr(ll x){
    	if(x==2) return 1;
    	if(x==1||!(x&1)) return 0;
    	
    	int k=0;
    	ll now,pre,ci=x-1,b;
    	
    	for(;!(ci&1);ci>>=1,k++);
    	
    	for(int i=1;i<=T;i++){
    		b=rand()%(x-2)+2;
    		
    		now=ksm(b,ci,x),pre=now;
    		
    		for(int j=1;j<=k;j++,pre=now){
    			now=mul(now,now,x);
    			if(now==1&&pre!=1&&pre!=x-1) return 0;
    		}
    		
    		if(now!=1) return 0;
    	}
    	
    	return 1;
    }
    
    inline ll Get(const ll x,const ll M){ return add(mul(x,x,M),A,M);}
    
    inline ll Pr(ll n,ll c){    
        for(ll i=2,k=2,x=rand()%(n-1)+1,y=x,d;;i++){
        	x=add(mul(x,x,n),c,n);
        	
        	d=gcd(llabs(x-y),n);
        	if(d>1&&d<n) return d;
        	
        	if(x==y) return n;
        	
        	if(i==k) y=x,k<<=1;
    	}
    }
    
    void Find(ll x){
    	if(Mr(x)){ zs[++cnt]=x; return;}
    	
    	ll p=x;
    	while(p==x) p=Pr(p,rand()%(x-1)+1);
    	
    	Find(p),Find(x/p);
    }
    
    /*
    int main(){
    //	freopen("data.in","r",stdin);
    //	freopen("data.out","w",stdout);
        
        
    //	srand(time(0));
    	
    	scanf("%lld",&N);
    	Find(N),sort(zs+1,zs+cnt+1);
    	
    	for(int i=1;i<=cnt;i++) ans*=(ll)(zs[i]==zs[i-1]?zs[i]:(zs[i]-1));
    	
    	printf("%lld
    ",ans);
    	
    	return 0;
    }
    */
    
    
    ll K;
    int inv[67];
    
    int C(ll x,int y){
        int an=inv[y];
        for(ll i=x-y+1;i<=x;i++) an=an*(ll)(i%ha)%ha;
        return an;
    }
    
    int main(){
        srand(time(0)+19260817);
        
        inv[1]=inv[0]=1;
        for(int i=2;i<=62;i++) inv[i]=-inv[ha%i]*(ll)(ha/i)%ha+ha;
        for(int i=2;i<=62;i++) inv[i]=inv[i]*(ll)inv[i-1]%ha;
        
        cin>>N>>K;
        
        if(N<=1e9){
            for(int i=2;i*(ll)i<=N;i++) while(!(N%i)) N/=i,zs[++cnt]=i;
            if(N!=1) zs[++cnt]=N;
        }
        else Find(N),sort(zs+1,zs+cnt+1);
        
        
        zs[cnt+1]=0;
        for(int i=1,tot=0;i<=cnt;i++){
            tot++;
            if(zs[i]!=zs[i+1]){
                ans=ans*(ll)C((ll)tot+K+1ll,tot)%ha;
                tot=0;
            }
        }
        
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9215079.html
Copyright © 2011-2022 走看看