数论--快速幂加欧拉筛法
作者:
YouKonwM3
,
2022-03-05 20:20:14
,
所有人可见
,
阅读 173
华华刚刚帮月月完成了作业。为了展示自己的学习水平之高超,华华还给月月出了一道类似的题:
Ans=\oplus_{i=1}^N(i^N\mod(10^9+7))Ans=⊕
i=1
N
(i
N
mod(10
9
+7))
\oplus⊕符号表示异或和,详见样例解释。
虽然月月写了个程序暴力的算出了答案,但是为了确保自己的答案没有错,希望你写个程序帮她验证一下。
输入描述:
输入一个正整数N。
输出描述:
输出答案Ans。
示例1
输入
复制
3
输出
复制
18
说明
N=3时,1^3=11
3
=1,2^3=82
3
=8,3^3=273
3
=27,异或和为18。
示例2
输入
2005117
输出
863466972
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 13e6 + 10;
const int mod = 1e9 + 7;
ll fastpow(ll a, ll b) //快速幂
{
ll ans = 1;
while (b)
{
if (b & 1)
ans = (ans * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ans;
}
ll prime[maxn], fac[maxn], cnt;
bool vis[maxn];
void solve(ll n)
{
fac[1] = 1; //初始化
for (int i = 2; i <= n; ++i)
{
if (!vis[i]) //如果这个数没有被访问
{
prime[++cnt] = i; //记录最小质数,用来筛去后面的数
fac[i] = fastpow(i, n); //求解当前的函数值
}
for (int j = 1; j <= cnt && i * prime[j] <= n; ++j)
{
vis[i * prime[j]] = 1;
fac[i * prime[j]] = fac[i] * fac[prime[j]] % mod; //公式
if (i % prime[j] == 0) //如果它不是这个数的最小质因子就跳过
break;
}
}
}
int main()
{
ll n, ans = 0;
scanf("%lld", &n);
solve(n);
for (int i = 1; i <= n; ++i)
ans ^= fac[i];
printf("%lld\n", ans);
}