链接: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;
}

 

相关文章: