题目:Lucky Chains

题意:

给定两个正整数a, b,若(a, b) = (a + 1, b + 1) = (a + 2, b + 2) = ... = (a + k, b + k) = 1,求 k 的最大值(k 的最大值可能为正无穷)

思路:由于最大公约数基础性质:\(gcd(a,b)=gcd(a,b-a)\)(当b > a时),我们可以推出:

\(gcd(a+k,b+k)=gcd(a+k,b-a)\)

注意到 b - a 为一个定值,由于\(b-a<=1e7\)我们可以在\(O(\sqrt{1e7})\)的时间内找出它的所有质因子,然后我们可以枚举 b - a 的所有质因子 p,

当\(gcd(a+t,p)>1\),即\(p|(a+t)\),k的最终取值为所有 t 的取值的最小值(从 0 到 t - 1,长度为 t),显然,t 的计算方法为\(p-a%p\),由于 a 可能时 p 的倍数,此时的结果因为 0,

因此 t 最终的计算方法为\((p-a\%p)\%p\)

由于有 1e6 组测试数据,所以时间复杂度为\(O(1e6*\sqrt{1e7})\),这显然会超时,超时代码如下:

#include <bits/stdc++.h>

int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
void solve() {
int a, b;
scanf("%d%d", &a, &b);
if (gcd(a, b) > 1) {
printf("0\n");
return;
}
if (a > b) {
std::swap(a, b);
}
if (b == a + 1) {
printf("-1\n");
return;
}
b -= a;
std::vector<int> primes;
auto getPrimes = [&]() -> void {
int tt = b;
for (int i = 2; i <= tt / i; ++i) {
if (tt % i == 0) {
while (tt % i == 0) {
tt /= i;
}
primes.push_back(i);
}
}
if (tt > 1) {
primes.push_back(tt);
}
};
getPrimes(); int res = 1e9;
for (auto p : primes) {
int k = (a / p + 1) * p - a;
res = std::min(res, k);
}
printf("%d\n", res);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
} return 0;
}

考虑对上述做法进行优化,我们直到线性筛法可以保证每一个合数只会被它的最小素因子筛掉,因此我们可以考虑在线性筛的过程中开一个数组 mp 来记录每一个数的最小质因子

我们先花去\(O(1e7)\)的时间筛出每一个数的最小素因子,然后对于每一次询问迭代的求出 a 的所有素因子,同时对结果进行计算,每次查询的时间复杂度不超过\(O(log(1e7))\),这样就可以通过本问题:

AC程序:

#include <bits/stdc++.h>

constexpr int N = 1e7;
int mp[N + 5]; // 存储每一个数的最小质因子
std::vector<int> primes; void solve() {
int a, b;
std::cin >> a >> b;
b -= a; if (b == 1) {
std::cout << -1 << '\n';
return;
} int res = 1e9;
while (b > 1) {
int p = mp[b];
b /= p;
res = std::min(res, (p - a % p) % p);
} std::cout << res << '\n';
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr); // 筛出每个数的最小质因子
for (int i = 2; i <= N; ++i) {
if (!mp[i]) {
mp[i] = i;
primes.push_back(i);
}
for (int j = 0; primes[j] <= N / i; ++j) {
mp[primes[j] * i] = primes[j];
if (i % primes[j] == 0) {
break;
}
}
} int T;
std::cin >> T;
while (T--) {
solve();
} return 0;
}

Lucky Chains(最大公约数的应用)的更多相关文章

  1. 代码的坏味道(20)——过度耦合的消息链(Message Chains)

    坏味道--过度耦合的消息链(Message Chains) 特征 消息链的形式类似于:obj.getA().getB().getC(). 问题原因 如果你看到用户向一个对象请求另一个对象,然后再向后者 ...

  2. C语言辗转相除法求2个数的最小公约数

    辗转相除法最大的用途就是用来求两个数的最大公约数. 用(a,b)来表示a和b的最大公约数. 有定理: 已知a,b,c为正整数,若a除以b余c,则(a,b)=(b,c). (证明过程请参考其它资料) 例 ...

  3. lucky 的 时光助理(2)

    lucky小姐说:昨天晚上他喝醉了,发消息说他想我了,说他后悔了. 我很惊讶. 我问lucky:你们很久都没有联系, 突然说... 你怎么想. 没错,'他'就是lucky的前男友. lucky看着我, ...

  4. lucky 的 时光助理

    2017年的lucky小姐,厌倦了现在的工作,她觉得这些的工作对于她而言不具备挑战性,她在迷茫春节过后该如何选择, 这里是距她走出校门整整一年的时光. lucky小姐从开发走向了实施,目的是想周游这个 ...

  5. ZOJ3944 People Counting ZOJ3939 The Lucky Week (模拟)

    ZOJ3944 People Counting ZOJ3939 The Lucky Week 1.PeopleConting 题意:照片上有很多个人,用矩阵里的字符表示.一个人如下: .O. /|\ ...

  6. 求两个数字的最大公约数-Python实现,三种方法效率比较,包含质数打印质数的方法

    今天面试,遇到面试官询求最大公约数.小学就学过的奥数题,居然忘了!只好回答分解质因数再求解! 回来果断复习下,常用方法辗转相除法和更相减损法,小学奥数都学过,很简单,就不细说了,忘了的话可以百度:ht ...

  7. BZOJ4488: [Jsoi2015]最大公约数

    Description 给定一个长度为 N 的正整数序列Ai对于其任意一个连续的子序列{Al,Al+1...Ar},我们定义其权值W(L,R )为其长度与序列中所有元素的最大公约数的乘积,即W(L,R ...

  8. 求N个数的最大公约数和最小公倍数(转)

    除了分解质因数,还有另一种适用于求几个较小数的最大公约数.最小公倍数的方法 下面是数学证明及算法实现 令[a1,a2,..,an] 表示a1,a2,..,an的最小公倍数,(a1,a2,..,an)表 ...

  9. 辗转相除法求最大公约数,非goto

    #include<iostream> using namespace std; //不推荐用goto,当然用它更快 //辗转相除法求两数的最大公约数 int gcd(long int a, ...

  10. ZOJ Problem Set - 1337 Pi 最大公约数

    这道题目的关键在于怎么求两个整数的最大公约数,这里正好复习一下以前的知识,如下: 1.设整数a和b 2.如果a和b都为0,则二者的最大公约数不存在 3.如果a或b等于0,则二者的最大公约数为非0的一个 ...

随机推荐

  1. Docker部署python-Flask应用

    title: Docker部署python Flask应用 date: 2022-11-19 13:00:25 tags: - python 环境 系统:windows10 python:python ...

  2. 如何使用MASA.Blazor

    MASA.Blazor 是什么? 基于Material Design设计和BlazorComponent的交互能力提供标准的基础组件库.提供如布局.弹框标准.Loading.全局异常处理等标准场景的预 ...

  3. VS针对Linux远程调试步骤

    VS2019下对于远程Linux下C++代码的调试 VS2017后新增了对跨平台代码的编写,编译和调试的功能,2019后更是新增了多种插件,以下是针对C++版本的linux环境代码调试 准备工作 安装 ...

  4. 1月3日内容总结——bbs项目登陆页面和主页、个人站点页的搭建

    目录 一.登陆功能完善 验证码功能实现 单机验证码实现验证码刷新(局部刷新) 点击登陆提交数据进行校验 二.主页搭建 html代码 views.py代码 主页内容部分 后台添加数据 分页器 前端获取头 ...

  5. drf-jwt、simplejwt的使用

    1.接口文档 # 前后端分离 -我们做后端,写接口 -前端做前端,根据接口写app,pc,小程序 -作为后端来讲,我们很清楚,比如登录接口 /api/v1/login/---->post---- ...

  6. CentOS7登录到控制台后无网络

    1.找到网卡配置文件 ll /etc/sysconfig/network-scripts/ | grep ifcfg-en 2.编辑配置文件开启系统启动时自动启动网络,并保存文件 vi /etc/sy ...

  7. JSON Crack 数据可视化工具

    JSON Crack简介 JSON Crack 是一个很方便的 JSON 数据可视化工具. 该项目不是简单的展示 JSON 数据,而是将其转化为类似思维导图的形式,支持放大/缩小.展开/收缩.搜索节点 ...

  8. 不像JVM的JVM

    1.面向对象 面向对象的思想:将功能封装到对象中,通过对象去实现 面向对象的目的:将复杂的事情简单化,将以前过程中的执行者变成了指挥者且符合现在人们的思考习惯 面向对象的三大特征: 封装:将对象的实现 ...

  9. .net core Autofac IOC 容器的简单使用

    书接上回,介绍了.net core 读取配置文件的几种方式,本文学习Autofac的同时再次增加一种读取配置文件的方法. 本文介绍Auofac,一个优秀的.NET IOC框架 源码地址:https:/ ...

  10. 树莓派3B+开启wifi

    1.打开树莓派配置 sudo raspi-config 2.选择 localisation options 3.选择 change Timezone,在里面选择亚洲ASIAN,里面选择地址,我选的上海 ...