492. Goblin's Appreciation
时间限制 1000 ms
内存限制 65536 KB
They give you a lot of pairs of numbers, denoted by K,N. for every input, you should tell them the sum of k^gcd(i,n), for i = 1~n.
For the answer is so large, you can give them the answer mod 23333.
输入格式
Given T, the number of cases. Then, for next T lines, there are two numbers K,N.(1 <= k <= 10^4, 1 <= n <= 10^8)
输出格式
For every case, print one line, containing the answer mod 23333.
输入样例
3
3 4
2 6
100 50000000
输出样例
96
84
3014
分析:10的8次方,直接算肯定超时。我们考虑与n的gcd相同的数的个数,gcd(i,n)=x————gcd(i/x,n/x)=1————即小于等于n/x且与x互质的数的个数,也就是欧拉函数。phi=n(1-1/p1)(1-1/p2)……(1-1/pn).
计算phi[n],直观感觉打表比每个暴力算要快,但是实际上我们只需要计算n的约数的phi值,个数远小于n本身(尤其是n很大时)。所以枚举n的约数,再逐个计算更快。而且打表为O(nlogn),10的8次方超时。
代码:#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #define MOD 23333 using namespace std; long long phi[1000001]; long long power[60]; void pp(long long k) { for(int i=1;i<=32;i++) { power[i]=k; k=k*k%MOD; } } long long mod_power(long long k,long long n) { long long res=1; int i=1; while(n) { if(n&1) res=res*power[i]%MOD; n>>=1; i++; } return res; } //O(根n)的复杂度 int euler_phi(int n) { int m=(int)sqrt(n+0.5); int ans=n; for(int i=2;i<=m;i++) { if(n%i==0) { ans=ans/i*(i-1); while(n%i==0) //将该约数除尽 n/=i; } } if(n>1) ans=ans/n*(n-1); return ans; } int main() { long long t,n,i,j,k,sum; scanf("%lld",&t); while(t--) { sum=0; scanf("%lld %lld",&k,&n); pp(k); int m=(int)sqrt(n+0.5); for(i=1;i<=m;i++) { if(n%i==0) { sum=(sum+mod_power(k,n/i)*euler_phi(i)%MOD)%MOD; if(n/i!=i) sum=(sum+mod_power(k,i)*euler_phi(n/i)%MOD)%MOD; } } printf("%lld\n",sum); } return 0; }