You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
const int N = 1e6 + 10 ;
const int MOD = 666623333 ;
//欧拉筛[线性筛法]
int primes [ N ] , cnt ; // primes[]存储所有素数
bool st [ N ] ; // st[x]存储x是否被筛掉
void get_primes ( int n ) {
for ( int i = 2 ; i < = n ; i + + ) {
if ( ! st [ i ] ) primes [ cnt + + ] = i ;
for ( int j = 0 ; primes [ j ] < = n / i ; j + + ) {
st [ primes [ j ] * i ] = true ;
if ( i % primes [ j ] = = 0 ) break ;
}
}
}
LL l , r , ans ;
//一维是[l,r]的映射位移,二维是一个动态数组,记录当前这个数字有哪些质数因子
vector < int > vec [ N ] ;
int main ( ) {
//输入
cin > > l > > r ;
//线性筛,筛出质数小因子范围
get_primes ( sqrt ( r ) ) ;
//遍历每个小质数因子
for ( int i = 0 ; i < cnt ; i + + ) {
int p = primes [ i ] ;
//1、利用数组下标的位移, 巧妙记录数据
//2、找到大于l的第一个p的倍数,然后, 每次增加p,相当于找出p的整数倍
for ( LL j = ( ( l - 1 ) / p + 1 ) * p ; j < = r ; j + = p )
vec [ j - l ] . push_back ( p ) ;
}
//如果还存在大的质数因子
for ( LL i = l ; i < = r ; i + + ) {
LL tmp = i ; //将i拷贝出来给了tmp,tmp要不断的减少啦, 而i要保留。
LL phi = i ; //欧拉函数值初始化为i
//当数字是i时, 找到对应的质因子列表中的每一个质数
for ( int p : vec [ i - l ] ) {
//这里需要仔细理解欧拉函数的基本求法
phi = phi / p * ( p - 1 ) ;
//如果还存在质数因子p, 就除干净为止,因为欧拉函数是与因子的幂次无关,只与因子有关
while ( ( tmp % p ) = = 0 ) tmp / = p ; //除干净为止
}
//如果还存在大的质数因子
if ( tmp > 1 ) phi = phi / tmp * ( tmp - 1 ) ;
//计算结果
ans = ( ans + i - phi ) % MOD ;
}
//输出答案
cout < < ans < < endl ;
return 0 ;
}