When we're done splitting up the data,
The sum of all the a^b is:
sum = [1+p1+p1^2+...+p1^ (a1*b)] * [1+p2+p2^2+...+p2^ (A2*B)] *...*[1+pn+pn^2+...+pn^ (an*b)].
At that time, the face of geometric series, thought of the summation formula, because the direct calculation timeout, but with the film division can not directly except, so think of the multiplication inverse, but the use of the inverse of the divisor and mod coprime, the topic to our film is not big enough, and then I side, do not know how to deal with, and then see the Internet To learn the method of equal-speed summation.
Its idea is the dichotomy + recursion, the law is as follows:
(1) If n is an odd number, there are even items, then:
1 + p + p^2 + p^3 +...+ p^n
= (1+p^ (n/2+1)) + p * (1+p^ (n/2+1)) +...+ p^ (N/2) * (1+p^ (n/2+1))
= (1 + p + p^2 +...+ p^ (N/2)) * (1 + p^ (n/2+1))
(2) If n is an even number, there are odd numbers, then:
1 + p + p^2 + p^3 +...+ p^n
= (1+p^ (n/2+1)) + p * (1+p^ (n/2+1)) +...+ p^ (n/2-1) * (1+p^ (n/2+1)) + p^ (N/2)
= (1 + p + p^2 +...+ p^ (n/2-1)) * (1+p^ (n/2+1)) + p^ (N/2);
As for the method of exponentiation, it can be obtained by fast exponentiation. The code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>using namespacestd;///sqrt (50000000) = 7071.07;///enough data///num = A1 (q^n-1)/(q-1);///method is difficult to useConst Long LongMod =9901;#defineMAXN 8000#defineLL Long LongLL A,b,p[maxn],e[maxn],tot;voidsplit () {intD = sqrt (A *1.0);///The prime factor is below its square roottot =0; Memset (E,0,sizeof(e)); for(inti =2; I <= D; i+=2) { if(A = =1) Break; if(a%i = =0) {P[tot]=i; while(a% i = =0) {a/=i; E[tot]++; } tot++; } if(i = =2) i--;///This method is efficient in finding primes } if(A! =1) {P[tot]=A; E[tot]++; Tot++; } for(inti =0; i < tot; i++) E[i]*=b; /*for (int i = 0;i < tot;i++) {printf ("p[%d] =%lld e[%d] =%lld\n", i,p[i],i,e[i]); }*/}ll Mypow (LL a,ll b) {if(b = =0)return 1; if(b = =1)returnAMod; if(b%2==0)returnMypow (((a%mod) * (a%mod))%mod,b/2)%Mod; Else return((a%mod) * MYPOW (a%mod,b-1)) %Mod;} ll Get_sum (ll A,ll b) {if(b==0)return 1; if(b%2)return((Get_sum (a,b/2) * (%mod) * (1+mypow (a,b/2+1))%mod)%Mod; Else return((Get_sum (a,b/2-1)%mod * (1+mypow (a,b/2+1)%mod)%mod + MYPOW (a,b/2)%mod)%Mod;}intMain () { while(~SCANF ("%i64d%i64d",&a,&b) {split (); LL ans=1; for(inti =0; I < tot;i++) {ans= ans * get_sum (p[i],e[i])%mod;///you can't omit it here .} printf ("%i64d\n", ans); } return 0;}
Note: There is a hard-to-find error, and it is not possible to use the Ansx= form when taking the film, and the difference in priority will make him overflow.
POJ 1845 Sumdiv (integer split + equal speed summation)