Codeforces 955C 数学

C. Sad powers

题意:
For each query you have to find the number of such x that L ≤ x ≤ R and there exist integer numbers a > 0, p > 1 such that x = a^p.
q个询问,每次求在区间 [L,R] 内有多少个幂。 q<=1e5, 1<=L<=R<=1e18。

tags:
数学题
首先肯定会想到预处理出 [1,1e18] 内所有的幂,但是指数为 2 的幂会有 1e9 个,所以我们先预处理出所有指数 >2 的幂,只有 1e6 级别。
然后对每个询问,指数为 2 的个数就直接开根号,指数 >2 的在预处理的数里面二分就好了。

//  955C
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 5000005;

ll  num[N];  int cnt;
void Init()
{
    cnt = 0;
    for(ll i=2; i<=1e6; ++i)
    {
        ll  sum = i;
        do {
            sum *= i;
            ll  tmp=(ll)sqrt(sum);
            if(tmp*tmp!=sum) num[++cnt]=sum;
        }while(sum<=1e18/i);
    }
    sort(num+1, num+1+cnt);
    cnt = unique(num+1, num+1+cnt) - (num+1);
}
ll  query(ll x) {
    int pos = upper_bound(num+1, num+1+cnt, x) - num;
    return pos-1;
}
ll  solve(ll L, ll R)
{
    ll  ret = ((ll)sqrt(R)) - ((ll)sqrt(L-1));
    return  ret + query(R) - query(L-1);
}
int main()
{
    Init();
    int q;  ll  L, R;
    scanf("%d", &q);
    while(q--)
    {
        scanf("%lld%lld", &L, &R);
        printf("%lld\n", solve(L, R));
    }

    return 0;
}

posted @ 2018-03-27 22:56  v9fly  阅读(191)  评论(0编辑  收藏  举报