首页 > 其他 > 详细

luoguP3601 签到题 质因数分解+欧拉函数

时间:2020-06-16 15:31:57      阅读:46      评论:0      收藏:0      [点我收藏+]

题不难,但是求欧拉函数的部分要注意一下:

求欧拉函数的时候是没有必要取模的,因为一定能除开.   

如果取模的话由于出题人没有保证存在逆元会出现错误.   

由于 $[L,R]$ 区间大小不超过 $10^6$,然后每个数最多只有一个大于根号 R 的质因子,所以可以筛出来 $10^6$ 

以内的质因数,然后调和级数来更新答案. 

code:     

#include <bits/stdc++.h>    
#define N 1000009   
#define ll long long 
#define mod 666623333  
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;     
ll L,R;     
bool vis[N];  
vector<int>g[N];
int prime[N],inv[N],cnt;    
ll qpow(ll x,ll y) 
{   
    ll tmp=1;  
    for(;y;y>>=1,x=x*x%mod) if(y&1) tmp=tmp*x%mod;  
    return tmp;   
}
ll INV(ll x) { return qpow(x,mod-2);  }   
void init() 
{    
    for(int i=2;i<N;++i) 
    {
        if(!vis[i]) prime[++cnt]=i;  
        for(int j=1;j<=cnt&&prime[j]*i<N;++j) 
        {
            vis[i*prime[j]]=1;  
            if(i%prime[j]==0) break;  
        }
    }     
    inv[1]=1;    
    for(int i=2;i<N;++i) inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;   
}
ll U(ll x,ll y) { return x%y==0?x/y:x/y+1;}
int main() 
{ 
    // setIO("input");  
    scanf("%lld%lld",&L,&R);          
    init();      
    for(int i=1;i<=cnt;++i)  
    {
        if(1ll*prime[i]*prime[i]>R) break;       
        for(ll j=U(L,prime[i])*1ll*prime[i];j<=R;j+=prime[i]) 
            g[j-L+1].push_back(prime[i]);          
    }   
    ll fin=0;   
    for(int i=1;i<=R-L+1;++i) 
    {        
        ll cur=1ll*i+L-1;  
        ll an=cur;     
        for(int j=0;j<g[i].size();++j) 
        {                 
            an=an/g[i][j]*(g[i][j]-1); 
            while((cur%g[i][j])==0) cur/=g[i][j];        
        }       
        if(cur>1) an=an/cur*(cur-1);             
        (fin+=1ll*i+L-1+mod-an)%=mod;  
    }   
    printf("%lld\n",fin);   
    return 0; 
}

  

 

luoguP3601 签到题 质因数分解+欧拉函数

原文:https://www.cnblogs.com/guangheli/p/13141134.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!