题目链接:https://ac.nowcoder.com/acm/contest/392/C
题意:给定n,求:
思路:令res[i]=iN (%MOD),因为xn是一个积性函数,即(x*y)n=xn*yn,那么我们利用线性筛,在筛的过程对素数i直接通过快速幂计算res[i],对合数利用res[i*prime[j]]=res[i]*res[prime[j]]%MOD来解,prime[j]是能整除i*prime[j]的第一个素数。因为素数有n/logn个,快速幂为logn,所以复杂度为O(n)。
AC代码:
#include<cstdio> using namespace std; const int maxn=1e7+3e6+5; const int MOD=1e9+7; typedef long long LL; bool vis[maxn]; LL n,prime[maxn],res[maxn]; int cnt,ans; LL qpow(LL a,LL b){ LL ret=1; while(b){ if(b&1) ret=(ret*a)%MOD; a=(a*a)%MOD; b>>=1; } return ret; } void sieve(){ res[1]=1; for(int i=2;i<=n;++i){ if(!vis[i]){ prime[cnt++]=i; res[i]=qpow(i,n); } for(int j=0;j<cnt&&i*prime[j]<=n;++j){ vis[i*prime[j]]=true; res[i*prime[j]]=res[i]*res[prime[j]]%MOD; if(i%prime[j]==0) break; } } } int main(){ scanf("%lld",&n); sieve(); for(int i=1;i<=n;++i) ans^=res[i]; printf("%d ",ans); return 0; }