链接:https://ac.nowcoder.com/acm/contest/392/C
来源:牛客网
1≤N≤1.3×1e7
题解
这道题如果先用快速幂算一下1到n每个数字的n次幂,然后异或,复杂度O(nlogn),就超时了;
这道题不用每个数都用快速幂来算,光算一下素数的就可以。下边引入一个积性函数的定义
积性函数的定义: f(ab)=f(a)f(b)
f(x)=x^n是一个积性函数,因为 f(ab)=(ab)^n=a^n* b^n=f(a)f(b)
所以可以用线性筛法来算。
质数大概有 n/logn 个,每个质数算一下快速幂复杂度logn, 所以总的时间复杂度是O(n);
引入大神的线性筛法的博客:https://www.cnblogs.com/grubbyskyer/p/3852421.html
代码
#include<algorithm>
#include <iostream>
#include<cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=1.3e7+5;
const ll mod=1e9+7;
int a[maxn];
bool prime[maxn];
int b[maxn];
int cnt;
ll f(ll x,ll y){
ll ans=1;
while(y){
if(y&1) ans=ans*x%mod;
y>>=1;
x=x*x%mod;
}
return ans;
}
int main(){
ll n;
cin>>n;
for(int i=2;i<=n;i++){
if(!prime[i]){
a[i]=f(i,n);
b[cnt++]=i;
}
for(int j=0;j<cnt;j++){
int x=i*b[j];
if(x>n) break;
prime[x]=true;
a[x]=a[i]*a[b[j]]%mod;
if(i%b[j]==0) break;
}
}
int ans=1;
for(int i=2;i<=n;i++) ans^=a[i];
cout<<ans<<endl;
return 0;
}