题目链接:传送门
题意:从1到n所有数的n次方的异或和。
分析:题目很简单,范围也不大,看完题目第一想法就是暴力,能过80%数据。那么就得转变思路,首先数据范围只有2e7,那么只有线性做法咯。首先得知道任意一个数x可以分为有限个素数相乘得到。那么xn 就可以分为一些素数的n次方相乘。接下就是用线性筛跑一遍来计算出所有数的n次方。
代码:
#include<iostream>
#define IOS ios::sync_with_stdio(false);
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<deque>
using namespace std;
typedef long long ll;
typedef double dd;
typedef pair<int, int> PII;
struct cmp{
bool operator() ( int a, int b){
return a> b;
}
};
const int N=2e7+10,mod=1e9+7;
int dx[4]={-1,0,0,1};
int dy[4]={0,1,-1,0};
int lowbit(int x){
return x&-x;
}
int n;
int prim[N];
int nu=0;
bool st[N];
int ans[N];//存储所有数的n次方
int qmi(int a,int b){
int res=1;
while(b){
if(b&1) res=(ll)res*a%mod;
a=(ll)a*a%mod;
b/=2;
}
return res;
}
void init(){
ans[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
prim[nu++]=i;
ans[i]=qmi(i,n);
}
for(int j=0;prim[j]*i<=n;j++){
st[prim[j]*i]=1;
ans[prim[j]*i]=(ll)ans[prim[j]]*ans[i]%mod;
if(i%prim[j]==0) break;
}
}
}
int main(){
cin>>n;
init();
int res=0;
for(int i=1;i<=n;i++){
res=res^ans[i];
}
cout<<res;
return 0;
}