【NOIP2017模擬】春思
阿新 • • 發佈:2019-02-07
Description
Data Constraint
Solution
首先可以先把A分解質因數,依照正常的套路一般都是在質因數上做文章。我們先想一想求某一個數的因數個數的方法,大概就是各質數組合而得,這題的想法也類似,想辦法把個個質數組合在一起。可以發現,如果把不同的質數分開計算就不會出現重複的情況,同時因為題目求的是因數的和,那我們就可以把某一個質數的答案直接加起來,因為計算滿足分配率。當前某一個質數的貢獻為
Code
#include<iostream>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
const int MO=9901,N=1e6+4;
#define fo(i,a,b) for(i=a;i<=b;i++)
struct arr{ll x,y;}a[N];
ll A,B,s[N],tot,num,sgm,ans;
int i,j,sum;
bool P[N];
void deal(int mx){
fo(i,2 ,mx){
if(!P[i]){s[++s[0]]=i,P[i]=1;}
fo(j,1,s[0]){
if(i*s[j]>mx) break;
P[i*s[j]]=1;
if(!(i%s[j])) break;
}
}
}
ll ksm(ll x,ll y){
ll z=1;for(;y;y/=2,x=x*x%MO)if(y&1)z=z*x%MO;
return z;
}
void calc(ll x,ll y){
num=(ksm(x ,y+1)-1+MO)%MO*ksm(x-1,MO-2)%MO;
num=(num-1+MO)%MO;
}
int main(){
scanf("%lld%lld",&A,&B);
deal(sqrt(A));
tot=A;
fo(i,1,s[0]){
if(!(tot%s[i])) a[++sum]=(arr){s[i]%MO,0};
while(!(tot%s[i])){
a[sum].y++;
tot/=s[i];
}
}
if(tot>1) a[++sum]=(arr){tot%MO,1};
fo(i,1,sum) a[i].y*=B;
ans=1;sgm=0;
fo(i,1,sum){
calc(a[i].x,a[i].y);
ans=(ans+sgm*num%MO)%MO;
sgm=(sgm+num+sgm*num%MO)%MO;
ans=(ans+num)%MO;
}
printf("%lld\n",ans);
}