YBT 1633:【例 3】Sumdiv
http://ybt.ssoier.cn:8088/problem_show.php?pid=1633
A^B
快速幂求结果,所有约数和,可以通过组合来进行得到。
技巧,通过递归得到1~n次的和.sum(n/2)*(1+?)这半,通过加自身和,调整后的自身以及补位,在log的时间内算出所有结果.
分解质因数,可以预先用素数,也可以奇偶法剪枝。
1 #include2 using namespace std; 3 typedef long long ll; 4 const ll mod=9901; 5 ll a,b,cnt; 6 const int N=1e5+520; 7 ll prime[N],n[N]; 8 ll qmi(ll x,ll y) 9 { 10 ll ans=1; 11 while(y) 12 { 13 if(y&1) ans=ans%mod*x%mod; 14 y>>=1; 15 x=x*x%mod; 16 } 17 return ans; 18 } 19 ll sum(ll p, ll k)//递归法求n次和。 20 { 21 if(k==0) return 1; 22 if(k&1) return (sum(p,k/2)*(1+qmi(p,k/2+1)))%mod; 23 else return (sum(p,k/2-1)*(1+qmi(p,k/2+1))+qmi(p,k/2))%mod; 24 } 25 void solve(ll a,ll b) 26 { 27 for(int i=2;i<=sqrt(a);) 28 { 29 if(a%i==0) 30 { 31 prime[++cnt]=i; 32 n[cnt]=0; 33 while(!(a%i)) n[cnt]++,a/=i; 34 } 35 if(i==2) i++;//奇偶法,或者筛选出来素数直接用 36 else i+=2; 37 } 38 if(a!=1) prime[++cnt]=a,n[cnt]=1; 39 ll ans=1; 40 for(int i=1;i<=cnt;i++) 41 { 42 ans=(ans*(sum(prime[i],n[i]*b))%mod)%mod; 43 } 44 cout< '\n'; 45 } 46 int main() 47 { 48 scanf("%lld%lld",&a,&b); 49 solve(a,b); 50 return 0; 51 }