poj1845(数论)
作者:互联网
传送门
求A^B的约数和%9901
这道题算是一道比较综合的题吧!
唯一分解定理那些的就不用说了
朴素求约数和:
^B就指数再乘个B好了
答案就是
然后get到一个新技能
A/B mod C = (A mod (B*C))/ B
简单证明:
然后还要注意的一点就是,计算的时候使用龟速乘,避免爆long long
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #define mod 9901 #define N 50000003 #define LL long long using namespace std; LL read() { LL f=1,x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } int notp[50003],prime[50003]; int tot=0; void init() { for(int i=2;i<=50000;++i) { if(!notp[i])prime[++tot]=i; for(int j=1;j<=tot&&i*prime[j]<=50000;++j) { notp[i*prime[j]]=1; if(i%prime[j]==0)break; } } } LL guicheng(LL a,LL x,LL p) { LL ans=0; while(x) { if(x&1)ans=(ans+a)%p; a=(a+a)%p;x>>=1; } return ans; } LL guipow(LL a,LL x,LL p) { LL ans=1; while(x) { if(x&1)ans=guicheng(ans,a,p)%p; a=guicheng(a,a,p)%p;x>>=1; } return ans; } int main() { init(); LL A=read(),B=read(); LL ans=1; LL a=A; for(int i=1;prime[i]*prime[i]<=a;++i) { if(a%prime[i]==0) { LL k=0; while(A%prime[i]==0){k++;A/=prime[i];} LL p=mod*(prime[i]-1); ans=ans*(guipow(prime[i],k*B+1,p)-1)/(prime[i]-1); ans%=mod; } } if(A>1) { LL p=mod*(A-1); ans=ans*(guipow(A,B+1,p)-1)/(A-1); ans%=mod; } printf("%lld\n",ans); }View Code
标签:数论,LL,long,while,ans,poj1845,include,mod 来源: https://www.cnblogs.com/yyys-/p/11311469.html