题意:给定a,b,c,d四个数字,要求猜出两个数字满足以下条件

1. a<x<=c,b<y<=d

2.gcd(x*y,a*b)==a*b

思路:要明晰一个规律,一个数的约数个数并不是随着它的大小增长的,具体的说,这个值增长的很慢,对于一个longlong上限的数来说,它的约数最多有大约1e6个。我们对gcd(x*y,a*b)==a*b这个条件做一个变换,转化为x*y为a*b的倍数。根据上文说的规律,我们分解出a,b的所有质因(注意,在eazy版当中你完全可以先将a*b再算它们的约数,因为它们相乘也不过1e10,最大的非本身质因子也不过1e5,这完全是够用的。但在hard版当中,就不能这么说了,虽然“总体上”,由于这个乘积数是1e9数的乘积,它绝大多数情况下的质因子都不会超过1e5,但是当a,b本身是质数时,这个局部适用的规律就被打破了,我们应当了解到,对于一个由低数量级的数乘来的大数,它的质因子“一般”小于等于较低数量级的开方,但当较低数量级的数本身为质数时,这个上限就被扩展到了较低数量级数本身,且最大有两个这个数量级的质因子),由于数量的数量级在1e6,状态空间较少,dfs爆搜出所有约数。

枚举约数,这里需要注意的是,如何选取x,y,固定一边,然后确定另一边吗? 这是较为常用的方法,但这个方式在这里是不适用的,原因在于约数的空间并不等同x,y的选择空间,我们枚举约数后,满足x*y是a*b的倍数后x=ves[i],y=a*b/ves[i],找到第一个小于等于c,d的并且为x,y倍数的数,如果满足调节1就是答案

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<string>
#include<bitset>
#include<cmath>
#include<array>
#include<atomic>
#include<sstream>
#include<stack>
#include<iomanip>
//#include<bits/stdc++.h>#define int ll
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);
#define pb push_back
#define endl '\n'
#define x first
#define y second
#define Endl endl
#define pre(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,b,a) for(int i=b;i>=a;i--)
#define si(x) scanf("%d", &x);
#define sl(x) scanf("%lld", &x);
#define ss(x) scanf("%s", x);
#define YES {puts("YES");return;}
#define NO {puts("NO"); return;}
#define all(x) x.begin(),x.end()using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;
typedef pair<char, int> PCI;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<ll, ll> PLL;
const int N = 200010, M = 2 * N, B = N, MOD = 998244353;
const double eps = 1e-7;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;//int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
int dx[8] = { 1,2,2,1,-1,-2,-2,-1 }, dy[8] = { 2,1,-1,-2,-2,-1,1,2 };
int n, m, k;
int prime[N], countNum;
bool st[N];ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lowbit(ll x) { return x & -x; }
ll qmi(ll a, ll b, ll MOD) {ll res = 1;while (b) {if (b & 1) res = res * a % MOD;a = a * a % MOD;b >>= 1;}return res;
}inline void init() {for (int i = 2; i < N; i++){if (!st[i]) prime[countNum++] = i;for (int j = 0; prime[j] * i < N; j++){st[i * prime[j]] = true;if (i % prime[j] == 0)break;}}
}void dfs(int p,ll now, vector<PII>& fact, vector<ll>& ves)
{if (p == fact.size()) {ves.push_back(now);return;}ll t = 1;for (int i = 0; i <= fact[p].y; i++){dfs(p + 1, now * t, fact, ves);if(i < fact[p].y)t *= fact[p].x;}
}bool check(int x, int jud,vector<ll>& ves)
{return ves[x] <= jud;
}void slove()
{int a, b, c, d;cin >> a >> b >> c >> d;vector<PII> fact;ll tmp = a;for (int i = 0; i < countNum; i++){if (tmp % prime[i] == 0){int s = 0;while (tmp % prime[i] == 0) tmp /= prime[i], s++;fact.pb({ prime[i],s });}}if (tmp > 1) fact.pb({ tmp,1 });tmp = b;for (int i = 0; i < countNum; i++){if (tmp % prime[i] == 0){int s = 0;while (tmp % prime[i] == 0) tmp /= prime[i], s++;fact.pb({ prime[i],s });}}if (tmp > 1) fact.pb({ tmp,1 });if (fact.empty()) { cout << c << ' ' << d << endl; return; }vector<ll> ves;dfs(0, 1, fact, ves);sort(all(ves));for (int i = 0; i<ves.size(); i++){ll x = ves[i], y = 1ll * a * b / x;y = d / y * y;x = c / x * x;if (x>a&&x<=c&&y>b&&y<=d) {cout << x << ' ' << y << endl;return;}}puts("-1 -1");return;
}signed main()
{//IOS;int _ = 1;si(_);init();while (_--){slove();}return 0;
}
/*
1
8437259 56761326 97110688 75779311*/

E2. Divisible Numbers (hard version)相关推荐

  1. Codeforces Round #828 (Div. 3) E2. Divisible Numbers (hard version)

    翻译: 这是这道题的难解版.简单版本和硬版本之间的唯一区别是对

  2. Codeforces Round #828 (Div. 3) E1. Divisible Numbers (easy version) 解题报告

    原题链接: Problem - E1 - Codeforces 题目描述: This is an easy version of the problem. The only difference be ...

  3. E1. Divisible Numbers (easy version)(数学)

    Problem - E1 - Codeforces 题意: 这是一个简单版本的问题.简单版和困难版的唯一区别是对a.b.c和d的限制. 给你4个正整数a.b.c.d,a<c,b<d.找到任 ...

  4. codeforces:E1. Divisible Numbers (easy version)【数论 + 复杂度计算 + 分解质因数】

    目录 题目截图 题目分析 想法1:遍历所有可能的xy(tle) 想法2:遍历可能的x(accepted) 总结 题目截图 题目分析 想法1,遍历所有kab作为xy的所有可能值,找到其所有因子,然后看看 ...

  5. codeforces1700数学:E2. Close Tuples (hard version)[组合计数 逆向统计] D. Circle Game[对称博弈考虑对称状态的胜负]

    E2. Close Tuples (hard version) 题目大意: 给定一个长度为n的序列a,给定一个长度为n的序列a,给定一个长度为n的序列a, 要从中挑选一个m元组(ai1,ai2,ai3 ...

  6. Codeforces Round #617 (Div. 3) E2. String Coloring (hard version) 思维 + dp + Dilworth定理

    传送门 文章目录 题意: 思路: 题意: 让你给一个串染色,不同颜色且相邻的一对字符可以互换位置,用最少的颜色,使交换后这个字符串字典序最小. 思路: 考虑将字符串分成若干个非递减的子序列,由于其非递 ...

  7. CodeForces - 1249C2 Good Numbers (hard version)(进制转换)

    题目链接:点击查看 题目大意:给出一个数n,求出一个大于等于n的"好数","好数"的规定是只由3的幂次之和构成 题目分析:直接将n拆成三进制,然后贪心从最高位开 ...

  8. E2. Square-free division (hard version) dp + 质因子分解

    传送门 文章目录 题意: 思路: 题意: 给你长度为nnn的数组,让后最多修改其中kkk个数(可以修改为任意数),让后问你分成的最少组是多少.这个组内元素是连续的且不存在任意两个数的积为平方数. 思路 ...

  9. ICPC焦作站(E、F)+思维+树上dp

    这场比赛依旧是三道题,E其实比我们出的D难一点,但确实在能力范围之内,出了就保底铜牌了,出的快的话说不定有银.策略很重要 E. Resistors in Parallel 大数+打表找规律. 最后得出 ...

最新文章

  1. 前端 重构时需要注意的事项_驾驶式扫地车的功能特点和使用时需要注意事项...
  2. linux文件夹加密访问,技术|Linux系统上用encfs创建和管理加密文件夹
  3. 第二章 MCS-51单片机硬件结构与工作原理
  4. 前端学习(2811):小程序学习之学习目录
  5. java代码鸟飞_180行原生js代码实现简易版飞行的小鸟游戏
  6. php 给富文本里的图片增加ALT、TITLE属性
  7. 高性能滚动 scroll 及页面渲染优化
  8. 小黑框运行java_初探Java类加载机制
  9. 由一道题目引发的为稳定与不稳定的排序思路
  10. 相机标定 棋盘格 图_【连载2.3.1】结构光系统标定
  11. CentOS 6.5下安装MySQL后重置root密码方法
  12. SPSS25安装教程
  13. 如何让双十一数据大屏讲出故事?设计有口诀
  14. 几个新的H5标签介绍
  15. web端--斗图Tenor api 接入
  16. 局域网ip冲突检测工具_只需一台Android设备就能打通局域网内部通讯:文字聊天与文件传输...
  17. 爱剪辑如何解决分段视频在串接处快两秒的问题
  18. AcWing蓝桥杯AB组辅导课07、贪心
  19. JS高频面试题,请查阅,务必收藏持续更新
  20. (二)地理信息中对地球的描述-地球的大地水准面、地球椭球体、大地基准面

热门文章

  1. 数据挖掘学习笔记01——数据挖掘的基本流程
  2. SAS中的intnx函数
  3. 黑马程序员————第三天
  4. 导致Android手机崩溃的壁纸,一张壁纸导致安卓手机崩溃作者首发声:绝非故意...
  5. C语言程序设计(2018-2019学年第一学期测试卷)
  6. 项目实训(十六)FPS游戏之PUN角色位移同步,动画状态同步
  7. mysql结果作为另一次查询_MySql中一次查询结果用作二次查询条件
  8. V8源码边缘试探-黑魔法指针偏移
  9. 谷粒商城基础篇------商品服务 - 三级分类(gulimall-product:pms_category表)
  10. 数据驱动VR流体仿真技能