求 区间[a,b]内满足p^k*q*^m(k>m)的数的个数

题目描述:

1<=a,b<=10^18,p,q都是素数  2<=p,q<=10^9;

求在[a,b]内可以表示为  x*p^k*q^m  k > m   的数的个数

分析:

由于要小于b,因此m一定小于 log10(b)/log10(p*q);

因此我们可以枚举m,中间计数的时候需要用到容斥。

具体看代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;

LL mypow(LL a,int b)
{
    LL ans = 1;
    while(b){
        if(b&1){
            ans=ans*a;
            b--;
        }
        b>>=1;
        a=a*a;
    }
    return ans;
}

int main()
{
    LL a,b,p,q;
    while(~scanf("%lld%lld%lld%lld",&a,&b,&p,&q)){
        int mmax = log10(b*1.0)/log10(p*q*1.0)+1;
        LL ans = 0;
        for(int i=0;i<=mmax;i++){
            if(mypow(p,i+1)>b*1.0/mypow(q,i))//防止爆long long
                break;
            for(int j=i+1;j<64;j++){
                if(mypow(p,j)>b*1.0/mypow(q,i)) break;//防止爆long long
                LL tmp=mypow(p,j)*mypow(q,i);
                LL cnt1 = b/tmp,cnt2=(a-1)/tmp;//由于是闭区间 因此要用a-1;
                ans += cnt1;
                ans -= cnt2;
                ans -= cnt1/p;
                ans -= cnt1/q;
                ans += cnt1/p/q;
                ans += cnt2/p;
                ans += cnt2/q;
                ans -=cnt2/p/q;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-08-27 11:04:07

求 区间[a,b]内满足p^k*q*^m(k>m)的数的个数的相关文章

求序列中满足Ai &lt; Aj &gt; Ak and i &lt; j &lt; k的组数 树状数组 HIT 2275 Number sequence

http://acm.hit.edu.cn/hoj/problem/view?id=2275 Number sequence   Source : SCU Programming Contest 2006 Final   Time limit : 1 sec   Memory limit : 64 M Submitted : 1632, Accepted : 440 Given a number sequence which has N element(s), please calculate

HDU 3473-Minimum Sum(划分树-求区间sigma最小值)

Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3710    Accepted Submission(s): 852 Problem Description You are given N positive integers, denoted as x0, x1 ... xN-1. Then give you

求区间最大公倍数

问题:求区间[a, b]内所有整数的最大公倍数 方法:利用公式:lcm(a, b) = |a*b|/gcd(a, b) 代码如下: 1 function Scm(a, b) { 2 function gcd(a, b) { 3 return b === 0 ? a : gcd(b, a%b); 4 } 5 function lcm(a, b) { 6 return a > b ? (a * b / gcd(a, b)) : (a * b / gcd(b,a)); 7 } 8 9 var scm

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s. And you have some query,each time you should calculate f(s[l...r]), s[l

HDU 4343 多查询求区间内的最大不相交区间个数-思维&amp;贪心-卡时间&amp;二分&amp;剪枝

题意:给你一些区间,现在有m个查询,求出每个查询的区间内的最大的不相交区间个数 分析: 几天前那道说谎问题时用dp的摞箱子模型求的最大的不相交区间个数,但是这题不能用这个方法,因为这题是动态的查询,不可能每个查询dp一次,超时. 这题用贪心策略.求区间[l~r]里的最大不相交区间,贪心策略就应该先选该区间内右端点最小的,这样给以后待选的区间留下更大的空间,所以我们的做法就是先按照区间的右端点排序,然后每次查询依次挑出查询区间里右端点最小的,并且把查询区间的左端点更新为刚才挑出的区间的右端点(这个

HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5101    Accepted Submission(s): 2339 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping abilit

Binary system(求区间内二进制中1的个数最多的数)

Description 给定一个范围[a,b]  (0<=a<b<=10^18) 求出该范围内二进制中1的个数最多的数,如果存在多个答案,输出最小的那个数 Input 输入数据有多组,每组数据输入两个整数a,b,表示区间[a, b]. Output 输出该区间内二进制的1最多的整数,如果有多个数二进制1的个数相同,输出最小的那个数. Sample Input 4 87 14 Sample Output 77 HINT 思路: 区间[a,b],如果a==b,输出a, 先把a,b化为二进制数

hdu3709(求区间内平衡数的个数)数位dp

题意:题中平衡数的定义: 以一个位置作为平衡轴,然后左右其他数字本身大小作为重量,到平衡轴的距离作为全职,实现左右平衡(即杠杆原理平衡).然后为区间[x,y]内平衡数的个数. (0 ≤ x ≤ y ≤ 1018) 解法:数位dp.如果一个数的平衡数,那么它的平衡轴位置是确定的.原来一直尝试数位dp在dfs时候列举平衡轴的位置,后来才意识到可以提前枚举平衡轴位置,然后再dfs,这样比较好写.dp[mid][pre][wei];表示对称轴是mid,计算第pre个位置以后需要力矩大小wei的数的个数.

POJ 2761-Feed the dogs(划分树)求区间内第k小的数

Feed the dogs Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 17679   Accepted: 5561 Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to feed the dogs every day for Wind. Jiajia loves Wind, but not the