zoukankan      html  css  js  c++  java
  • Integer’s Power HDU

    找出(l,r)内的所有的指数最大的次方和

    因为一个数可能可以看成a^b和c^d,所以我需要去重,从后往前枚举幂数,然后找可以整除的部分,把低次幂的数去掉。

    然后开n方的部分,先用pow()函数找到最接近答案的数,但是会丢失精度,然后在这个数的附近寻找最接近答案的整数,用快速幂在乘n次幂回去,看最接近原本数的是哪一个。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lowbit(x) (x & (-x))
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const double pi = 4.0*atan(1.0);
    const int inf = 0x3f3f3f3f;
    const int maxn = 100;
    const int maxm = 200010;
    const int mod = 998244353;
    const double eps = 1e-8;
    using namespace std;
    
    ll n, m;
    int T, tol;
    ll num[70];
    ll INF = 1e18;
    
    ll qpow(ll a, ll b) {
        ll ans = 1;
        while(b) {
            if(b&1) {
                double tmp = 1.0 * INF / ans;
                if(a > tmp)        return -1;
                ans = ans * a;
            }
            b >>= 1;
            if(a > ((ll)1<<31) && b)    return -1;
            a = a*a;
        }
        return ans;
    }
    
    ll calc(ll x,  int pos) {
        ll a = (ll)pow((double)x, 1.0/pos);
        ll ansl = qpow(a-1, pos);
        ll ansm = qpow(a, pos);
        ll ansr = qpow(a+1, pos);
        if(ansr != -1 && ansr <= x)        return a+1;
        if(ansm != -1 && ansm <= x)        return a;
        return a-1;
    }
    
    ll solve(ll x) {
        memset(num, 0, sizeof num);
        num[1] = x;
        int pos = 2;
        for(; pos <= 64; pos++) {
            ll tmp = calc(x, pos) - 1;
            if(tmp <= 0)    break;
            num[pos] = tmp;
        }
        pos--;
        for(int i=pos; i>=1; i--) {
            for(int j=2; i*j<=pos; j++) {
                num[i] -= num[i*j];
            }
        }
        //for(int i=1; i<=pos; i++)    printf("%I64d%c", num[i], i==pos ? '
    ' : ' ');
        ll ans = 0;
        for(int i=1; i<=pos; i++)    ans += i * num[i];
        return ans;
    }
    
    int main() {
        while(scanf("%I64d%I64d", &n, &m), n||m) {
            ll ans = solve(m);
            ans -= solve(n-1);
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    基于antlr的表达式解析器
    ANTLR语法层的选项及动作
    Understanding ANTLR Grammar Files
    写给Git初学者的7个建议
    Top 8 Diagrams for Understanding Java
    技术面不深入
    一个初级程序员学习新技术的策略
    SoftReference,WeakReference&WeakHashMap
    探索Antlr(Antlr 3.0更新版)
    Five minute introduction to ANTLR 3
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9473284.html
Copyright © 2011-2022 走看看