题意

给你 \(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\) 以内的质因子加快枚举。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define pb push_back
#define re(x) memset(x, 0, sizeof x)
inline int gi() {
int x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
return x * f;
}
template <typename T> inline void Max(T &a, T b){if(a < b) a = b;}
template <typename T> inline void Min(T &a, T b){if(a > b) a = b;}
const int N = 1e5 + 7;
const LL inf = 1e18 + 7;
int T, qc;
bool vis[N], ans[N];
LL dis[N];
struct qs {
LL n, k; int id;
bool operator <(const qs &rhs) const {
return k < rhs.k;
}
}q[N];
struct data {
int u;LL dis;
bool operator <(const data &rhs) const {
return rhs.dis < dis;
}
};
priority_queue<data>Q;
vector<LL> pf;
void dijk(int n) {
for(int i = 0; i < n; ++i) dis[i] = inf;
memset(vis, 0, sizeof vis);
dis[0] = 0;Q.push((data){ 0, 0}); while(!Q.empty()) {
int u = Q.top().u;Q.pop();
if(vis[u]) continue;vis[u] = 1;
for(int i = 1; i < pf.size(); ++i) {
int v = (u + pf[i]) % n;
if(dis[u] + pf[i] >= 0 && dis[u] + pf[i] < dis[v]) {
dis[v] = dis[u] + pf[i];
Q.push((data){ v, dis[v]});
}
}
}
}
void exgcd(LL a, LL b, LL &x, LL &y) {
if(!b) { x = 1, y = 0; return;}
exgcd(b, a % b, y, x); y -= x * (a / b);
}
const int num_sz = 5e7 + 7;
int t, pc;
int pri[num_sz];
bool visp[num_sz];
void pre(int n) {
int to;
for(int i = 2; i <= n; ++i) {
if(!visp[i]) pri[++pc] = i;
for(int j = 1; (to = i * pri[j]) <= n; ++j) {
visp[to] = 1;
if(i % pri[j] == 0) break;
}
}
}
int main() {
pre(5e7);
T = gi();
rep(i, 1, T) {
LL a, b;
scanf("%lld%lld", &a, &b);
q[++qc] = (qs){ a, b, i};
}
sort(q + 1, q + 1 + qc);
int cnt = 0;
for(int i = 1, j = 1; i <= T; i = j + 1, j = i) {
pf.clear();
while(j + 1 <= T && q[j + 1].k == q[j].k) ++j; LL x = q[i].k;
for(int k = 1, l = (int)sqrt(x); k <= pc && pri[k] <= l; ++k) if(x % pri[k] == 0){
while(x % pri[k] == 0) x /= pri[k];
pf.pb(pri[k]);
}
if(x > 1) pf.pb(x);
if(pf.empty()) continue;
if(pf.size() == 1) {
for(int k = i; k <= j; ++k)
ans[q[k].id] = q[k].n % q[k].k == 0;
continue;
}
if(pf.size() == 2) {
LL x, y, inva;
exgcd(pf[0], pf[1], x, y);
inva = (x + pf[1]) % pf[1];
for(int k = i; k <= j; ++k)
ans[q[k].id] =pf[0] * (q[k].n % pf[1] * inva % pf[1]) <= q[k].n;
continue;
}
sort(pf.begin(), pf.end());
dijk(pf[0]);
for(int k = i; k <= j; ++k)
ans[q[k].id] = dis[q[k].n % pf[0]] <= q[k].n;
}
for(int i = 1; i <= T; ++i) puts(ans[i] ? "YES": "NO");
return 0;
}

[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. EJB2.0 ejb-jar.xml配置文件详解

    <ejb-jar><!--EJB发布描述器的根元素,它包含一个可选的EJB-JAR文件的描述,可选显示的名称,可选小图标的文件名,可选的大图标的文件名,必须的所有被包含的enterp ...

  2. Linux中 /proc/[pid] 目录各文件简析

    Linux 内核提供了一种通过 proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc 文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系 ...

  3. 转:sqlserver 临时表、表变量、CTE的比较

    1.临时表 1.1 临时表包括:以#开头的局部临时表,以##开头的全局临时表. 1.2 存储 不管是局部临时表,还是全局临时表,都会放存在tempdb数据库中. 1.3 作用域 局部临时表:对当前连接 ...

  4. python基础学习1

    一.python第一个程序 print("hello world") 二.变量的命名规则 1. 字母数字下划线组成 2. 不能以数字开头,不能含有特殊字符和空格 3. 不能以保留字 ...

  5. python下wxpython程序国际化的实践(中文英文切换)

    一.什么是python的国际化(I18N) 有关I18N,百度上解释一大堆,个人比较喜欢这个说法. i18n是 Internationalization 这个英文的简写,因为International ...

  6. Questions about UIUC and USC

    Questions about UIUC and USC I am admitted to University of Illinois at Urbana-Champaign (UIUC) Prof ...

  7. docker18.ce harbor 安装

     Harbor 是什么? harbor VMware 开发的一个容器镜像仓库,harbor的功能提供用户权限管理.镜像复制等功能,提高使用的registry的效率. 安装最新版的docker可以参考d ...

  8. SNMP协议利用

    1.安装snmp服务 2.配置snmp服务 运行Services.msc 添加社区public,只读 启动服务 3.在kali运行 Snmpwalk -c public -v 2c IP 即可查看目标 ...

  9. 阿里八八Alpha阶段Scrum(3/12)

    今日进度 叶文滔: 实现了悬浮按钮的拖动. 问题困难:第三方库调入不成功,多级悬浮按钮的实现仍未完成. 刘晓: 完成注册.修改密码的UI部分,创建了注册Activity,修改密码Activity. 问 ...

  10. Camstar MES 5.8 發現Ajax事件失效

    從Camstar4.5升級到5.8後,發現原來用戶在4.5下可以正常使用的不良信息收集功能,列出的不良只有第一頁可以顯示,無法自動裝載下一頁. 嘗試發出,IE以下這個選項沒有選中,選中後,就可以正常工 ...