P3601 签到题

P3601 签到题

题目背景

这是一道签到题!

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

题目描述

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

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

输入输出格式

输入格式:

 

一行两个整数,l、r。

 

输出格式:

 

一行一个整数表示答案。

 

输入输出样例

输入样例#1:
233 2333
输出样例#1:
1056499
输入样例#2:
2333333333 2333666666
输出样例#2:
153096296

说明

对于30%的数据,

对于60%的数据,

对于100%的数据,

分析:每个数枚举质因数显然超时;

   所以,换个角度就是预处理出sqrt(r)的素因子,然后枚举其倍数;

   最后欧拉函数即可;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
const int maxn=1e6+10;
using namespace std;
inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
inline void umax(ll &p,ll q){if(p<q)p=q;}
inline void umin(ll &p,ll q){if(p>q)p=q;}
inline ll read()
{
    ll x=0;int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,k,t,cnt[maxn],all;
bool vis[maxn];
ll l,r,ret,p[maxn],num[maxn];
void init()
{
    for(int i=2;i<=maxn-10;i++)
    {
        if(vis[i])continue;
        for(int j=2*i;j<=maxn-10;j+=i)
        {
            vis[j]=true;
        }
        cnt[all++]=i;
    }
}
void gao()
{
    for(int i=0;i<all;i++)
    {
        ll l1=l%cnt[i]==0?l:(l/cnt[i]+1)*cnt[i],r1=r/cnt[i]*cnt[i];
        if(l1>r1)continue;
        for(ll x=l1;x<=r1;x+=cnt[i])
        {
            p[x-l]-=p[x-l]/cnt[i];
            while(num[x-l]%cnt[i]==0)
                num[x-l]/=cnt[i];
        }
    }
    for(int i=0;i<=r-l;i++)if(num[i]>1)p[i]-=p[i]/num[i];
}

int main()
{
    int i,j;
    init();
    scanf("%lld%lld",&l,&r);
    for(ll x=l;x<=r;x++)p[x-l]=num[x-l]=x;
    gao();
    for(ll x=l;x<=r;x++)ret=(ret+x-p[x-l])%666623333;
    printf("%lld\n",ret);
    return 0;
}
posted @ 2017-02-02 16:58  mxzf0213  阅读(310)  评论(0编辑  收藏  举报