【题解】Sumdiv

【题解】Sumdiv

传送门

根据组合的乘法原理,一个数的所有约数和

\[sum=\prod_{i=1} \Sigma_j^{a_i} p_i^j \]

所以任务就变成了分解\(A\)的质因数,分解出的\(a_i\)每个乘上一个\(B\)然后套公式就好了。

但是要求一个\(\Sigma_j^{a_i} p_i^j​\),分治就好了了。

写的代码过不去,但是

\(update:\)搞清楚了,特判\(b=0,A=0\)这种情况...duliu

就很绝望

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define int long long
using namespace std;typedef long long ll;
#define DEBUG printf("Passed %s in LINE %d\n",__FUNCTION__,__LINE__)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define RP(t,a,b)  for(register int t=(a),edd=(b);t<=edd;++t)
#define ERP(t,a)   for(register int t=head[a];t;t=e[t].nx)
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lef l,mid,pos<<1
#define rgt mid+1,r,pos<<1|1
#define pushup(pos) (seg[pos]=seg[pos<<1]+seg[pos<<1|1])
TMP inline ccf qr(ccf b){
    register char c=getchar();register int q=1;register ccf x=0;
    while(c<48||c>57)q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
    return q==-1?-x:x;}
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
TMP inline ccf READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
const int mod=9901;
//----------------------template&IO---------------------------
int pr[101];
int ai[101];
int A,B;
int ans=1;

inline int ksm(int base,int p){register int ret=1;
    for(register int t=p;t;t>>=1,base=(base*base)%mod) if(t&1) ret*=base,ret%=mod;
    return ret%mod;
}

inline int sum(int base,int n){
    if(not n) return 1;
    if(n==1) return base%mod+1;
    register int sav=sum(base,n>>1);
    if(n&1) return sav*(1LL+ksm(base,(n>>1)+1))%mod;
    return (sav*(1LL+ksm(base,(n>>1)))%mod-ksm(base,n>>1)%mod+mod)%mod;
}

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    A=qr(1);B=qr(1);
    if(not A) return cout<<0<<endl,0;
    if(not B) return cout<<1<<endl,0;
    for(register int t=2;t*t<=A;++t){
	if(A%t==0){
	    pr[++pr[0]]=t;
	    while(A%t==0) A/=t,++ai[pr[0]];
	}
    }
    
    if(A>1) pr[++pr[0]]=A,ai[pr[0]]=1;
    RP(t,1,pr[0])
	ans=ans*sum(pr[t],ai[t]*B)%mod;
    cout<<ans<<endl;
    return 0;
}

posted @ 2019-03-10 21:59  谁是鸽王  阅读(720)  评论(0编辑  收藏  举报