zoukankan      html  css  js  c++  java
  • sumdiv 算术基本定理的推论

    sumdiv

    Sol:

    直接把A质因数分解,由算术基本定理的推论可知:

    [ans=prod^{cnt}_{i=1}(sum^{B*c_i}_{j=0}p_i^j) (mod 9901) ]

    可以发现,里面每一项都是一个等比数列求和,那么:

    [ans=prod^{cnt}_{i=1}(frac{p_i^{B*c_i+1}-1}{p_i-1}) (mod 9901) ]

    所以可以直接算答案了。

    需要注意的是,如果:

    [9901 | p_i-1 ]

    那么不能直接求其逆元,但是:

    [p_iequiv 1 (mod 9901) ]

    所以

    [sum^{B*c_i}_{j=0}p_i^jequiv B*c_i+1 (mod 9901) ]

    同样可以直接算答案。

    Code:

    #include<cstdio>
    #include<cstring>
    #define RG register
    #define IL inline
    #define int long long
    #define DB double 
    using namespace std;
    
    const int N=2e4+10;
    const int mod=9901;
    
    int A,B,tot,fac[N],cnt[N];
    
    IL void prime_fac(int x) {
    	RG int i;
    	for (i=2;i*i<=x;++i)
    		if (x%i==0) {
    			fac[++tot]=i;
    			while (x%i==0) x/=i,++cnt[tot];
    		}
    	if (x>1) fac[++tot]=x,cnt[tot]=1;
    }
    
    IL int mul(int a,int b) {
    	RG int ans=0;
    	for (;b;b>>=1,a=(a+a)%mod)
    		if (b&1) ans=(ans+a)%mod;
    	return ans;
    }
    
    IL int quick_pow(int x,int P) {
    	RG int ans=1;
    	for (;P;P>>=1,x=mul(x,x))
    		if (P&1) ans=mul(ans,x);
    	return ans;
    }
    
    signed main()
    {	
    	RG int i,ans;
    	while (scanf("%lld%lld",&A,&B)!=EOF) {
    		memset(cnt,0,sizeof(cnt));
    		tot=0,ans=1,prime_fac(A);
    		for (i=1;i<=tot;++i) {
    			if ((fac[i]-1)%mod==0) ans=mul(ans,(cnt[i]*B+1));
    			else {
    				ans=mul(ans,(quick_pow(fac[i],cnt[i]*B+1)-1+mod)%mod);
    				ans=mul(ans,quick_pow(fac[i]-1,mod-2));
    			}
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    反射详解六
    反射详解五
    反射详解四
    反射详解三
    反射详解二
    mysql行转列
    mysql增删改查
    视图的使用
    js过滤
    错误集
  • 原文地址:https://www.cnblogs.com/Bhllx/p/10653883.html
Copyright © 2011-2022 走看看