题意

给你 \(n\) 和 \(k\) ,问能否用 \(k\) 的所有 \(>1\) 的因子凑出 \(n\) 。多组数据,但保证不同的 \(k\) 不超过 50 个。

\(n\leq 10^{18}, k\leq 10^{15}\)

分析

  • 记 \(k\) 的质因子数量为 \(m\) 。
  1. 如果 \(k=1\) 一定不行。

  2. 如果 \(m=1\) 直接判断是否可以整除。

  3. 如果 \(m=2\) 就是求 \(ax+by=n\) 是否存在非负整数解。

    根据 \(ax \equiv n\ (mod\ b)\) 可以得到 \(x\equiv na^{(-1)}\ (mod\ b)\)

    只需要判断最小的 \(x*a\) 是否 \(\le n\) 即可。

  4. 如果 \(m\ge 3\) 一定存在一个最小质因子 \(\le 10^5\) ,此时就可以套用同余最短路来求解了。

    具体地,我们将最小质因子单独拿出来,答案可以写成 \(n\%p+kp​\) 的形式,当且仅当 \(n\%p​\) 可以用其他质因子凑出,且他们的和 \(\le n​\) 时才能凑出 \(n​\) 。利用最短路求解这种转移成环的问题。

  • 主要复杂度在处理质因子,可以记录 \(5\times 10^7\) 以内的质因子加快枚举。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. #define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
  5. #define rep(i, a, b) for(int i = a; i <= b; ++i)
  6. #define pb push_back
  7. #define re(x) memset(x, 0, sizeof x)
  8. inline int gi() {
  9. int x = 0,f = 1;
  10. char ch = getchar();
  11. while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
  12. while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
  13. return x * f;
  14. }
  15. template <typename T> inline void Max(T &a, T b){if(a < b) a = b;}
  16. template <typename T> inline void Min(T &a, T b){if(a > b) a = b;}
  17. const int N = 1e5 + 7;
  18. const LL inf = 1e18 + 7;
  19. int T, qc;
  20. bool vis[N], ans[N];
  21. LL dis[N];
  22. struct qs {
  23. LL n, k; int id;
  24. bool operator <(const qs &rhs) const {
  25. return k < rhs.k;
  26. }
  27. }q[N];
  28. struct data {
  29. int u;LL dis;
  30. bool operator <(const data &rhs) const {
  31. return rhs.dis < dis;
  32. }
  33. };
  34. priority_queue<data>Q;
  35. vector<LL> pf;
  36. void dijk(int n) {
  37. for(int i = 0; i < n; ++i) dis[i] = inf;
  38. memset(vis, 0, sizeof vis);
  39. dis[0] = 0;Q.push((data){ 0, 0});
  40. while(!Q.empty()) {
  41. int u = Q.top().u;Q.pop();
  42. if(vis[u]) continue;vis[u] = 1;
  43. for(int i = 1; i < pf.size(); ++i) {
  44. int v = (u + pf[i]) % n;
  45. if(dis[u] + pf[i] >= 0 && dis[u] + pf[i] < dis[v]) {
  46. dis[v] = dis[u] + pf[i];
  47. Q.push((data){ v, dis[v]});
  48. }
  49. }
  50. }
  51. }
  52. void exgcd(LL a, LL b, LL &x, LL &y) {
  53. if(!b) { x = 1, y = 0; return;}
  54. exgcd(b, a % b, y, x); y -= x * (a / b);
  55. }
  56. const int num_sz = 5e7 + 7;
  57. int t, pc;
  58. int pri[num_sz];
  59. bool visp[num_sz];
  60. void pre(int n) {
  61. int to;
  62. for(int i = 2; i <= n; ++i) {
  63. if(!visp[i]) pri[++pc] = i;
  64. for(int j = 1; (to = i * pri[j]) <= n; ++j) {
  65. visp[to] = 1;
  66. if(i % pri[j] == 0) break;
  67. }
  68. }
  69. }
  70. int main() {
  71. pre(5e7);
  72. T = gi();
  73. rep(i, 1, T) {
  74. LL a, b;
  75. scanf("%lld%lld", &a, &b);
  76. q[++qc] = (qs){ a, b, i};
  77. }
  78. sort(q + 1, q + 1 + qc);
  79. int cnt = 0;
  80. for(int i = 1, j = 1; i <= T; i = j + 1, j = i) {
  81. pf.clear();
  82. while(j + 1 <= T && q[j + 1].k == q[j].k) ++j;
  83. LL x = q[i].k;
  84. for(int k = 1, l = (int)sqrt(x); k <= pc && pri[k] <= l; ++k) if(x % pri[k] == 0){
  85. while(x % pri[k] == 0) x /= pri[k];
  86. pf.pb(pri[k]);
  87. }
  88. if(x > 1) pf.pb(x);
  89. if(pf.empty()) continue;
  90. if(pf.size() == 1) {
  91. for(int k = i; k <= j; ++k)
  92. ans[q[k].id] = q[k].n % q[k].k == 0;
  93. continue;
  94. }
  95. if(pf.size() == 2) {
  96. LL x, y, inva;
  97. exgcd(pf[0], pf[1], x, y);
  98. inva = (x + pf[1]) % pf[1];
  99. for(int k = i; k <= j; ++k)
  100. ans[q[k].id] =pf[0] * (q[k].n % pf[1] * inva % pf[1]) <= q[k].n;
  101. continue;
  102. }
  103. sort(pf.begin(), pf.end());
  104. dijk(pf[0]);
  105. for(int k = i; k <= j; ++k)
  106. ans[q[k].id] = dis[q[k].n % pf[0]] <= q[k].n;
  107. }
  108. for(int i = 1; i <= T; ++i) puts(ans[i] ? "YES": "NO");
  109. return 0;
  110. }

[CF986F]Oppa Funcan Style Remastered[exgcd+同余最短路]的更多相关文章

  1. Codeforces 986F - Oppa Funcan Style Remastered(同余最短路)

    Codeforces 题面传送门 & 洛谷题面传送门 感谢此题教会我一个东西叫做同余最短路(大雾 首先这个不同 \(k\) 的个数 \(\le 50\) 这个条件显然是让我们对每个 \(k\) ...

  2. CF986F Oppa Funcan Style Remastered

    CF986F Oppa Funcan Style Remastered 不错的图论转化题! 题目首先转化成:能否用若干个k的非1因数的和=n 其次,因数太多,由于只是可行性,不妨直接都用质因子来填充! ...

  3. codeforces986F Oppa Funcan Style Remastered【线性筛+最短路】

    容易看出是用质因数凑n 首先01个因数的情况可以特判,2个的情况就是ap1+bp2=n,b=n/p2(mod p1),这里的b是最小的特解,求出来看bp2<=n则有解,否则无解 然后剩下的情况最 ...

  4. 「CF986F」 Oppa Funcan Style Remastered

    「CF986F」 Oppa Funcan Style Remastered Link 首先发现分解成若干个 \(k\) 的因数很蠢,事实上每个因数都是由某个质因子的若干倍组成的,所以可以将问题转换为分 ...

  5. [Codeforces 485F] Oppa Funcan Style Remastered

    [题目链接] https://codeforces.com/contest/986/problem/F [算法] 不难发现 , 每个人都在且仅在一个简单环中 , 设这些环长的长度分别为 A1, A2 ...

  6. Codeforces 516E - Drazil and His Happy Friends(同余最短路)

    Codeforces 题面传送门 & 洛谷题面传送门 首先思考一个非常简单的性质:记 \(d=\gcd(n,m)\),那么每次在一起吃完饭的男女孩编号必定与 \(d\) 同余,而根据斐蜀定理可 ...

  7. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  8. HDU 6071 Lazy Running (同余最短路 dij)

    Lazy Running Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)To ...

  9. BZOJ 2118 墨墨的等式 (同余最短路)

    题目大意:已知B的范围,求a1x1+a2x2+...+anxn==B存在非负正整数解的B的数量,N<=12,ai<=1e5,B<=1e12 同余最短路裸题 思想大概是这样的,我们选定 ...

随机推荐

  1. go语言练习:接口

    package main import ( "fmt" ) type Run interface { //这个接口的名字命名成Car更直观一点,除了distance方法外,后面可以 ...

  2. Git删除文件

    Git基础 Git有三大区(工作区.暂存区.版本库),文件有三个状态(untracked.unstaged.uncommited). (1)打开项目文件夹,除了隐藏的.git文件夹,其他项目文件位于的 ...

  3. SQL 时间戳转换为日期

    , '1970-01-01 00:00:00') 其中Timestamp为10位的时间戳,+8*3600是获取中国北京时间(东八区)

  4. RSA 非对称加密,私钥转码为pkcs8 错误总结

    RSA 非对称加密,私钥转码为pkcs8 错误总结 最近在和某上市公司对接金融方面的业务时,关于RSA对接过程中遇到了一个坑,特来分享下解决方案. 该上市公司简称为A公司,我们简称为B公司.A-B两家 ...

  5. PHP 与 YAML

    PHP 与 YAML 这一段时间都没有写blog,并不是因为事情多,而是自己变懒了.看到新技术也不愿意深入思考其背后的原理,学习C++语言了近一个多月,由于学习方法有问题,并没有什么项目可以练手.靠每 ...

  6. 不使用 vue-cli 与 vue 模版,使用 Vue2.x + webpack4.x 从零开始一步步搭建项目框架

    说明 这是我根据慕课网上的一个课程 Vue+Webpack打造todo应用 过程一步步搭下来的框架,去掉了业务相关的逻辑. 项目最终的效果包括了引入vue框架:使用CSS预处理器:使用babel:引用 ...

  7. js 小数计算时出现多余的数据

    根据资料显示:是由于十进制换算成二进制,处理后,再由二进制换算成十进制时,造成的误差. 得出:所以(0.1+0.2)!=0.3 而是=0.30000000000000004的结果 解决方法: 参考:h ...

  8. Alpha冲刺&总结报告(12/12)(麻瓜制造者)

    各个成员今日完成的任务 邓弘立: 完成了上传头像的功能 符天愉: 对所有接口进行了再次测试 江郑: 完成了发布需求接口部分的进一步测试和接口文档的编写 刘双玉: 完成了商品信息接口部分的进一步测试和接 ...

  9. 【PyCharm疑问】在pycharm中带有中文时,有时会导致程序判断错误,是何原因?

    1.会导致程序打印false错误的代码如下: # -*- coding:utf-8 -*- import os import sys from uiautomator import device as ...

  10. docker-compose.md

    安装 pip python 2.7+的系统同yum先安装pip命令. # yum install -y python2-pip # pip install docker-compose 网络安装 # ...