CodeChef November Challenge 2013 » Yet Another Cute Girl

题目:Yet Another Cute Girl 

Chef doesn't love math anymore. He loves Sasha. Sashen'ka is cute.

Chef goes on a date with her. Flowers are boring, while numbers are not. He knows that most of all this girl loves numbers, that's why he is going to bring ribbon with numbers L, L+1, L+2, ..., R written on it.

Sasha thinks that numbers with prime number of divisors are special. That's why she is going to kiss boy for each such number he will bring.

Now Chef wonder how many times he will be kissed by Sashen'ka ?

 

Input

The first line of the input contains an integer T denoting the number of test cases. The description of Ttest cases follows.
The first line of each test case contains two number L, R.

 

Output

For each test case, output a single line containing answer for corresponding test case.

 

Constraints

  • 1 ≤ T ≤ 5
  • 1 ≤ L ≤ R ≤ 1012
  • 0 ≤ R-L ≤ 106

 

Example

Input:
1
1 10

Output:
6

 

Explanation

Example case 1. Numbers 2,3,4,5,7,9 are special.



思路:就是求区间内素数的个数,再加上一个prime[i]^(prime[j]-1)的形式的个数


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define maxn 1000100
long long num[79000];
bool prime[maxn];
int n_prime=0;
bool cnt[1000001];
map<long long,int>m;
vector<long long>v;
long long l,r;
void Prime()
{
    memset(prime,true,sizeof(prime));
    prime[0]=prime[1]=0;
    for(int i=2;i<maxn;i++)
        if(prime[i])
        {
            num[++n_prime]=i;
            for(int j=2*i;j<maxn;j+=i)
                prime[j]=0;
        }
    //cout<<n_prime<<":"<<num[n_prime]<<endl;
}
void make_prime()
{
    m.clear();
    long long tmp;
    memset(cnt,true,sizeof(cnt));
    for(int i=1;i<=n_prime;i++)
    {
        tmp=l/num[i];
        while(tmp*num[i]<l||tmp<=1)
            tmp++;
        for(long long j=tmp*num[i];j<=r;j+=num[i])
        {
            if(j>=l&&j<=r)
                cnt[j-l]=0;
        }
    }
    if(l==1)
        cnt[0]=0;
    for(long long i=0;i+l<=r;i++)
        if(cnt[i]&&i+l<=r&&i>=0)
            m[i+l]++;
}
long long Pow(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans*=a;
        }
        else
        {
            b/=2;
            a*=a;
        }
    }
    return ans;
}
int main()
{
    Prime();
    long long tmp;
    v.clear();
    for(int i=1;i<n_prime && num[i]*num[i]<1e12;i++)
    {
        for(int j=2;j<n_prime;j++)
        {
 
            tmp=Pow(num[i],num[j]-1);
            if(tmp>1e12)
                break;
            v.push_back(tmp);
        }
    }
    sort(v.begin(),v.end());
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld",&l,&r);
        make_prime();
        printf("%d\n",m.size()+(upper_bound(v.begin(),v.end(),r)-lower_bound(v.begin(),v.end(),l)));
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值