2021-08-08

Hankson的趣味题

链接: [link]https://www.luogu.com.cn/problem/P1072

题目:

Hanks 博士是 BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫 Hankson。

现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数。

现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:

已知正整数 a0,a1,b0,b1,设某未知正整数 x 满足:

1.x 和 a0 的最大公约数是 a1;
2.x 和 b0 的最小公倍数是 b1。
Hankson 的“逆问题”就是求出满足条件的正整数 x。

但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。

因此他转而开始考虑如何求解满足条件的 x 的个数。

输入格式

输入第一行为一个正整数 n,表示有 n 组输入数据。

接下来的 n 行每行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。

输入数据保证 a0 能被 a1 整除,b1 能被 b0 整除。

输出格式
输出共 n 行。

每组输入数据的输出结果占一行,为一个整数。

对于每组数据:若不存在这样的 x,请输出 0;

若存在这样的 x,请输出满足条件的 x 的个数;

数据范围

1≤n≤2000,

1≤a0,a1,b0,b1≤2∗10^9

题意:

给出四个数a0,a1,b0,b1。一个整数x,使得gcd(a0,x)=a1,lcm(b0,x)=b1,求满足这个条件的x的个数

思路:

因为x和b0的最小公倍数b1,所以x一定是b的约数,我们最开始想到的方法就是找出b1的所有的约数,然后一个个去判断是否符合条件,在这里如果我们采用试除法的话,时间复杂度是n√b1=2000√21e9≈1e8,就有可能有组数据会超时,所以我们可以换种做法,我们可以把1~√b1间所有的质数筛选出来,然后再dfs一遍,把b1的所有的质因子留下,这样时间复杂度大约是n√b1/log(b1)≈1e7,最后在跑一遍,判断一下即可。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int prim[N],cnt=0;
bool vis[N];
int h[1600],d=0,ct; //h 数组来存符合条件的质数
struct node{
    int num,p;
}f[16];  //f 来存 1~√b1间的所有素数  num 为质数 p为个数
void prime() {
    vis[0] = vis[1] = true;
    memset(vis,0,sizeof vis);  
    for (int i = 2; i <= N; i++) {
        if (!vis[i]) prim[cnt++] = i;
        for (int j = 0; i * prim[j] < N; j++) {  //线性筛求质数
            vis[i * prim[j]] = true;
            if (i % prim[j] == 0) break;
        }
    }
}
int gcd(int a,int b) {
    return b ? gcd(b, a % b) : a;
}
void dfs(int u,int x) {
    if (u == ct) {
        h[d++] = x;
        return;
    }
    for (int i = 0; i <= f[u].p; i++) {
        dfs(u + 1, x);
        x *= f[u].num;   
    }
}
int main() {
    prime();
    int  t;
    cin >> t;
    while (t--) {
        int a, b, c,e;
        ct = 0;
        cin >> a >> b >> c >> e;
        int k=e;
        for (int i = 0; prim[i] * prim[i] <= k; i++) {
            int p = prim[i];
            if (k % p == 0) {
                int s = 0;
                while (k % p == 0) k /= p, s++;
                f[ct++] = {p, s};
            }
        }
        if (k > 1) f[ct++] = {k, 1};
        d = 0;
        dfs(0, 1);
        int res = 0;
        for (int i = 0; i < d; i++) {
            int u = h[i];
            if (gcd(u, a) == b && (ll) c *u  / gcd(u, c) == e) res++;
        }
        cout << res << '\n';
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ffmpeg-2021-08-08-git-ac0408522a是一个开源的音视频处理工具,它可以在多个平台上进编译和安装。该版本是2021年8月8日的最新版本,使用了ac0408522a的Git提交ID。 full_build表示这个版本是一个完整的构建版本,它包含了所有的功能和模块。在编译过程中,会将ffmpeg的所有件和依赖项都包含进去,以便用户可以使用和访问所有的功能。 通过使用该版本的ffmpeg,用户可以进各种音视频处理任务,例如转码、剪辑、合并、分割、提取音频等等。它支持多种音视频格式,包括但不限于MP4、AVI、MKV、MP3、AAC等。用户可以根据自己的需求选择不同的输入和输出格式,并且可以自定义各种编解码参数。 此外,ffmpeg还提供了丰富的命令选项和参数,以便用户可以灵活地控制和配置转码过程。用户可以通过给定不同的命令选项来指定输入文件、输出文件、编码方式、视频尺寸、比特率、帧率等等,以达到不同的处理目的。 需要注意的是,由于ffmpeg是一个功能强大且复杂的工具,对于初学者来说可能需要一定的学习和实践才能熟练掌握。因此,建议用户在使用之前先阅读官方文档或者参考相关教程,以便更好地了解和使用ffmpeg的功能。 ### 回答2: ffmpeg-2021-08-08-git-ac0408522a-full_build 是一个版本号为 ac0408522a 的 ffmpeg 软件的完整构建版。 FFmpeg 是一个开源的音视频处理工具,能够对音视频进转码、混流、剪辑等操作。它提供了很多功能丰富的命令工具,可以满足各种音视频处理需求。 这个版本的 ffmpeg 是在 2021 年 8 月 8 日基于 ac0408522a 提交的代码所编译而成。ac0408522a 是版本的特定标识符,用于追踪、识别和检索代码库中的不同版本。 full_build 表示这个版本是基于完整构建进的,即所有功能和特性都被包含在内。这意味着在这个版本中,你可以使用 FFmpeg 提供的所有命令和选项,无需额外编译或安装其他附加件。 对于想要使用 FFmpeg 进音视频处理的用户来说,这个完整构建版提供了方便和易用性。用户可以通过命令调用 ffmpeg 工具,并根据自己的需求使用不同的参数和选项,完成各种音视频处理任务,如转码、剪辑、添加字幕、提取音频等等。 由于 FFmpeg 是一个持续更新和发展的开源项目,新的版本可能会修复漏洞、增加新的功能或性能改进。因此,使用最新的版本可以获得更好的用户体验和更高的稳定性。 总之,ffmpeg-2021-08-08-git-ac0408522a-full_build 是基于 ac0408522a 提交的代码所编译而成的一个完整构建版的 FFmpeg 软件,用户可以使用其中的功能丰富的命令工具来进音视频处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值