小白練習賽12☞C.華華給月月出題

題目描述

華華剛剛幫月月完成了作業。爲了展示自己的學習水平之高超,華華還給月月出了一道類似的題:
Ans=i=1N(iNmod(109+7))Ans=\bigoplus_{i=1}^N(i^N mod (10^9+7))
\bigoplus符號表示異或和,詳見樣例解釋。
雖然月月寫了個程序暴力的算出了答案,但是爲了確保自己的答案沒有錯,希望你寫個程序幫她驗證一下。

輸入描述:

輸入一個正整數N。

輸出描述:

輸出答案Ans。

note:

1N1.31071\leq N\leq 1.3*10^7

看完題目忍不住要給數學大佬們獻上膝蓋

題解:
F(n)=i=1N(f(i)),f(x)=xNmod(109+7)F(n)=\bigoplus_{i=1}^N(f(i)), f(x)=x^Nmod(10^9+7)
f(xy)=f(x)f(y)\because f(x*y)=f(x)*f(y)
f(x)\therefore f(x)是積性函數
所以可以預處理[1, N]的素數集的f(x)f(x),而[1,N]非素數的f(x)f(x)可以通過積性函數的性質得到。
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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章