题目
输入n(n<=1e7+3e6),输出ans
思路来源
官方题解
https://ac.nowcoder.com/discuss/160376?type=101&order=0&pos=5&page=1
思路来源
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=40396589
题解
显然,是完全积性函数,
有
在x和y不互质的时候也成立
先用快速幂把素数的答案处理出来,
考虑到欧拉筛筛合数,用一次就会筛掉这个数,
那么,就在筛掉的这一次时,更新这个合数的ans值即可
线性筛,素数个数
,每次对素数快速幂
,
故最终复杂度为
心得
本是一道水题,但由于自己对完全积性函数理解并不深
做的时候并不会做,这式子看着也觉得挺吓人
现在补上了就好了QAQ
代码
#include<iostream>
#include<cstdio>
#include<cstring>
const int maxn=1e7+3e6+10;
const int mod=1e9+7;
typedef long long ll;
bool ok[maxn];
int prime[maxn],cnt;
int n;
ll ans[maxn];
ll modpow(ll x,ll n)
{
ll res=1;
for(;n;x=x*x%mod,n/=2)
if(n&1)res=res*x%mod;
return res;
}
void sieve(int n)
{
ans[1]=1;
for(ll i=2;i<=n;++i)
{
if(!ok[i])
{
prime[cnt++]=i;
ans[i]=modpow(i,n);
}
for(int j=0;j<cnt;++j)
{
if(i*prime[j]>n)break;
ok[i*prime[j]]=1;
ans[i*prime[j]]=ans[i]*ans[prime[j]]%mod;
if(i%prime[j]==0)break;
}
}
}
ll solve(int n)
{
ll res=0;
for(int i=1;i<=n;++i)
res^=ans[i];
return res;
}
int main()
{
scanf("%d",&n);
sieve(n);
printf("%lld\n",solve(n));
return 0;
}