题目描述
华华刚刚帮月月完成了作业。为了展示自己的学习水平之高超,华华还给月月出了一道类似的题:
⊕符号表示异或和,详见样例解释。
虽然月月写了个程序暴力的算出了答案,但是为了确保自己的答案没有错,希望你写个程序帮她验证一下。
输入描述:
输入一个正整数N。
输出描述:
输出答案Ans。
输入
3
输出
18
说明
示例2
输入
2005117
输出
复制
863466972
备注:
PS:第一次遇见这种题目直接傻眼了,不知道这是一个积性函数,这个概念也没听说过,然后取学习了相关知识,不仅被这个题目所折服,这个题目实在太巧妙了。
推荐罗永军老师的博客积性函数的前世今生
1.首先做这个题目肯定需要快速幂,下面给出模板
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;
}
2.其次,我们需要了解欧拉筛与积性函数之间的关系,这个题目需要求前n项的异或和就需要用到积性函数的性质,加上欧拉筛就能很好的解决这个问题,并且时间复杂度很低,下面给出欧拉筛的代码
欧拉筛
int prime[MAXN]; //保存质数
int vis[MAXN]; //记录是否被筛
int euler_sieve(int n){
//欧拉筛。返回质数的个数。
int cnt = 0; //记录质数个数
memset(vis,0,sizeof(vis));
memset(prime,0,sizeof