Niu Ke-Huahua presents questions for the month and month (prime sieve + fast power)

Topic link

Meaning of the question:
ask for
Insert picture description here
n<=1.3*10^7.

Problem solution:
I thought it was a template problem at first, so I used the quick exponentiation to find it directly, but it was tle. After reading the solution, I know that we must first sift prime numbers.
Because each number can be expressed as the multiplication of some prime numbers, we can express a certain composite number x as the smallest prime factor of x=x*y. Then x^n = the smallest prime factor of x^n * y^n. Then in the process of prime number sieve, we can find the nth power of all elements. Doing so can reduce the number of times to use fast powers and greatly reduce the complexity.

Code:

#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;
}

Guess you like

Origin blog.csdn.net/weixin_45755679/article/details/113488197