洛谷P1593 因子和

题目链接:https://www.luogu.com.cn/problem/P1593

题意:求A^B的所有因子之和模9901。

分解A=p1^a1*p2^a2*...*pk^ak,B次方后再利用约数和公式得答案为π(1+pi+pi^2+...+pi^(ai*B))%9901

下面简单讨论pi的取值,设当前乘积中的一项为S。1)若9901|pi,则当前项S=1(mod 9901);2)若9901|pi-1,则S=ai*B+1(mod 9901);3) 上述情况均不成立,则对于每一项可以用等比数列求和为S=(pi^(ai*B+1)-1)/(pi-1)(mod 9901)。分子用快速幂直接算,分母用费马小定理求逆元即可(因为9901为素数且除去了情况2,此时pi-1对9901有逆元),更新ans=ans*S%9901得到最后的ans

(顺便吐槽一下poj1845的奇怪数据

 1 #include<iostream>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const ll m=9901;
 6 const ll maxm=1000+10;
 7 const ll maxn=5000+10; 
 8 ll A,B,t[maxn];
 9 int p[maxm],pr[maxn];
10 int i,j,cnt;
11 
12 ll qpow(ll a,ll b){
13   ll res=1;
14   while (b){
15     if (b&1) res=res*a%m;
16     a=a*a%m;
17     b>>=1;
18   }
19   return res;
20 }
21 
22 int main(){
23     cin>>A>>B;
24     //
25     for (i=2;i<maxm;i++){
26       if (p[i]==0)
27         for (j=i+i;j<maxn;j+=i) p[j]=1;
28     }
29     //分解质因数 
30     for (i=2;i*i<=A;i++)
31       if (p[i]==0&&A%i==0){
32         int num=0;
33           while (A%i==0){
34             num++;A/=i;
35         }
36         pr[++cnt]=i;t[cnt]=num*B;
37       }
38     if (A>1){
39       pr[++cnt]=A;t[cnt]=B;
40     }//
41     ll ans=1;
42     for (i=1;i<=cnt;i++){
43       if ((pr[i]%m==0)) continue;
44       else if ((pr[i]-1)%m==0) ans=ans*(t[i]+1)%m;
45       else ans=ans*(qpow(pr[i],t[i]+1)-1+m)%m*qpow(pr[i]-1,m-2)%m;
46     }
47     cout<<ans<<endl;
48     return 0;
49 }
洛谷P1593

 

posted @ 2020-05-25 19:46  coastal_taipan  阅读(142)  评论(0编辑  收藏  举报