題目描述
華華剛剛幫月月完成了作業。爲了展示自己的學習水平之高超,華華還給月月出了一道類似的題:
符號表示異或和,詳見樣例解釋。
雖然月月寫了個程序暴力的算出了答案,但是爲了確保自己的答案沒有錯,希望你寫個程序幫她驗證一下。
輸入描述:
輸入一個正整數N。
輸出描述:
輸出答案Ans。
note:
看完題目忍不住要給數學大佬們獻上膝蓋
題解:
設
所以可以預處理[1, N]的素數集的,而[1,N]非素數的可以通過積性函數的性質得到。
code
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1.3e7+10;
const long long mod = 1e9+7;
bool prime[maxn];
int w[maxn], cnt = 0;
long long f[maxn];
int n;
long long Pow(long long x, long long p){
long long ans = 1;
while(p){
if(p & 1) ans = (ans*x)%mod;
x = (x*x)%mod;
p>>=1;
}
return ans;
}
void solve(){
for(int i = 2; i <= n; i++){
if(prime[i]) continue;
f[i] = Pow(i, n);
w[cnt++] = i;
for(int j = i<<1; j <= n; j+=i){
prime[j] = true;
}
}
long long ans = 1;
for(int i = 2; i <= n; i++){
if(!prime[i]) ans^=f[i];
else{
int k = i;
for(int j = 0; j < cnt; j++){
if(i%w[j]==0){
f[i] = (f[w[j]]*f[i/w[j]])%mod;
break;
}
}
ans^=f[i];
}
}
printf("%lld\n", ans);
}
int main(){
scanf("%d", &n);
solve();
return 0;
}