《P3601 签到题》

发布于:2025-04-09 ⋅ 阅读:(31) ⋅ 点赞:(0)

题目背景

这是一道签到题!

建议做题之前仔细阅读数据范围!

题目描述

我们定义一个函数:qiandao(x) 为小于等于 x 的数中,与 x 不互质的数的个数。

这题作为签到题,给出 l 和 r,求出:

i=l∑r​qiandao(i)mod666623333

输入格式

一行两个整数,l、r。

输出格式

一行一个整数表示答案。

输入输出样例

输入 #1复制

233 2333

输出 #1复制

1056499

输入 #2复制

2333333333 2333666666

输出 #2复制

153096296

说明/提示

  • 对于 30% 的数据,l,r≤103。
  • 对于 60% 的数据,l,r≤107。
  • 对于 100% 的数据,1≤l≤r≤1012,r−l≤106。

代码实现;

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll Mn=1e6+5;
const ll mod=666623333;
ll prime[Mn],l,r,phi[Mn],vis[Mn],pc,ans,a[Mn];

void getprime(){
  for(ll i=2;i<Mn;i++){
    if(a[i])
      prime[pc++] = i;
    for(ll j=0;j<pc && prime[j]*i<Mn;j++){
      a[prime[j]*i]=false;
      if(i%prime[j]==0)
        break;
    }
  }
}

int main(){
  scanf("%lld%lld" ,&l,&r);
  for(int i=0;i<Mn;i++)a[i]=true;
  getprime();
  for(ll i=l;i<=r;i++){
    vis[i-l]=i;
    phi[i-l]=i;
  }
  for(ll i=0;i<pc && prime[i]*prime[i]<=r;i++){
    ll p=prime[i],start=l;
    if(l%p!=0){
      start=l/p*p+p;
    }
    for(ll j=start;j<=r;j=j+p){
      phi[j-l]=phi[j-l]/p*(p-1);
      while(vis[j-l]%p==0)
        vis[j-l]/=p;
    }
  }
  for(ll i=l;i<=r;i++){
    if(vis[i-l]>1){
      //处理剩下的大因子,最多有一个超过根号r的因子。
      phi[i-l]=phi[i-l]/vis[i-l]*(vis[i-l]-1);
    }
    ans=(ans+(i-phi[i-l]))%mod;
  }
  printf("%lld\n",ans);
  return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到