题意:
求
n<=1.3*10^7。
题解:
一开始还以为是个模板题,直接用快速幂去求,但是tle了。看了题解才知道,要先筛素数。
因为每个数都可以表示成一些质数相乘,所以我们对于某个合数x,可以表示成 x=x的最小质因子*y。那么x^n= x的最小质因子^n * y^n。那么在素数筛的过程就我们就可以求出所有元素的n次方。这样做可以减少使用快速幂的次数,大大降低了复杂度。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=13e6+5;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int prime[MAXN];
bool is_prime[MAXN];
ll fac[MAXN];
ll fastpow(ll a, ll b) //快速幂
{
ll ans = 1;
while (b)
{
if (b & 1)
ans = (ans * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ans;
}
void solve(int n)
{
fac[1]=1;
int p=0;
for(int i=2;i<=n;i++)
{
is_prime[i]=true;
}
is_prime[0]=is_prime[1]=false;
for(int i=2;i<=n;i++)
{
if(is_prime[i])
{
prime[p++]=i;
fac[i]=fastpow(i,n);
}
for(int j=0;j<p&&i*prime[j]<=n;j++)
{
is_prime[i*prime[j]]=false;
fac[i*prime[j]]=fac[i]*fac[prime[j]]%mod;
if(i%prime[j]==0) break;
}
}
}
int main()
{
int n;
cin>>n;
solve(n);
int ans=0;
for(int i=1;i<=n;i++)
{
ans=ans^fac[i];
}
cout<<ans<<endl;
}