原题链接:
HDU-6063
RXD and math
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 672 Accepted Submission(s): 385
Problem Description
RXD is a good mathematician.
One day he wants to calculate:
output the answer module 109+7.
1≤n,k≤1e18
p1,p2,p3…pk are different prime numbers
Input
There are several test cases, please keep reading until EOF.
There are exact 10000 cases.
For each test case, there are 2 numbers n,k.
Output
For each test case, output “Case #x: y”, which means the test case number and the answer.
Sample Input
10 10
Sample Output
Case #1: 999999937
大意:
给公式求值。
思路:
比赛的时候想着套莫比乌斯函数,同时也发现
μ(n)2
不是 0 就是 1 。
然后队长说发现 n^k 直接取模试试看就过了。
赛后题解:
现在从答案来反向理解一下= =
题解不是很明白。如果只是从原式去推的话,就很难得出 n^k 这种简洁的结论。
每个数字 x 都能唯一表示 a2×b=x 。
对于 |μ(i)|=1 的情况,
归纳起来
每一个 i , 式子 * 对应的是 i的倍数 在 n^k 内的数量
而 i 取 1~n^k 的范围时,i 和其倍数把所有 1~n^k 都表示了。
所以答案就是个数 即 n^k
代码实现:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
//#define LOCAL
const int mod = 1e9+7;
ll quick_mod(ll a,ll b){
a%=mod;
ll ret=1;
while(b){
if(b&1)
ret=(ret*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ret%mod;
}
int main() {
ll a,b,kase=0;
while(scanf("%lld%lld",&a,&b)!=EOF){
printf("Case #%lld: %lld\n",++kase,quick_mod(a,b));
}
return 0;
}