题目传送门:洛谷 P5345

很荣幸为 X Round 1 贡献了自己的一题。

题意简述:

给定 \(n\) 组 \(k_i,g_i,r_i\)(\(0\le k_i,r_i<g_i\le 10^7\))。

求关于 \(x\) 的方程组 \(\left\{\begin{matrix}k_1^x\equiv r_1\pmod{g_1}\\k_2^x\equiv r_2\pmod{g_2}\\\vdots\\k_n^x\equiv r_n\pmod{g_n}\end{matrix}\right.\)(定义 \(0^0=1\))在 \([0,10^9]\) 内的最小整数解,或判断在这个范围内无解。

题解:

分为两个部分解决。

第一部分:分别求出每个方程的解。

首先观察 \(k^j\bmod g\) 的规律,以 \(g=495616\),\(k=124\) 为例:

定义 \(f(i)=ki\bmod g\),则把每个在 \([0,g)\) 之间的整数看作一个节点后,形成了一个基环内向森林。

从 \(1\bmod g\) 开始走唯一的出边,必然形成一个 \(\rho\) 形结构,让我们模拟这个过程:

可以看到,出现了长度为 \(5\) 的循环。

  1. 如果 \(r=245760\),则 \(x\equiv 7\pmod{5}\),且 \(x\ge 7\)。

  2. 如果 \(r=12544\),则 \(x=4\)。

  3. 如果 \(r=2\),则无解。

以上就是每个方程的 \(3\) 种解,无限解,唯一解或无解。

那么,问题就是,如何区分这 \(3\) 种解,以及如何求出解。

首先,需要将 \(\rho\) 形的“尾巴”和循环分开考虑,不难证明“尾巴”的长度不超过 \(\log_2g\)。

而且可以发现,若在“尾巴”上找到了解,那么就只有一组解。所以需要判断一个值是否在尾巴上。

其实这是很简单的,如果 \(\gcd(x,m)\neq\gcd(f(x),m)\),那么 \(x\) 就在尾巴上,反之就在循环内。

据此,我们区分了在“尾巴”上的解,也就是只有一组解的情况,接下来考虑不在“尾巴”上的情况。

因为解不在“尾巴”上,则如果解不在循环内就是无解了,所以首先判断解是否在循环内。

假设第一个在循环上的数为 \(c\),尾巴长度为 \(o\),则有 \(c\equiv k^o\pmod{g}\)。

令 \(d=\gcd(c,g)\),则原方程 \(k^x\equiv r\pmod{g}\) 可化为 \(c\cdot k^{x-o}\equiv r\pmod{g}\) 且 \(x\ge o\),这是因为我们假定解一定在循环内。

可以进一步化为 \(k^{x-o}\equiv\frac{r}{d}\left(\frac{c}{d}\right)^{-1}\pmod{\frac{g}{d}}\),若 \(r\) 不是 \(d\) 的倍数则无解。

这是因为循环内的值均是 \(d\) 的倍数,可以让方程同除 \(d\),又因为 \(\frac{c}{d}\perp\frac{g}{d}\),可以取逆元。

令 \(a=k,b=\frac{r}{d}\left(\frac{c}{d}\right)^{-1},m=\frac{g}{d}\),则有 \(a\perp m\)。

使用 BSGS 求出 \(a^y\equiv b\pmod{m}\) 的最小自然数解 \(y\) 后,有原方程的最小自然数解为 \(y+o\)。

再使用 BSGS 求出 \(a^z\equiv 1\pmod{m}\) 的最小正整数解 \(z\),即 \(a\) 对 \(m\) 的阶。

则原方程的解为 \(x\equiv y+o\pmod{z}\) 且 \(x\ge y+o\)。

至此,第一部分解决。

第二部分:合并每个方程的解。

首先,若前面的方程出现了无解的情况,则方程组也无解。

若前面的方程出现了只有唯一解的情况,只需要检查此唯一解是否满足所有方程即可。

接下来讨论以上每个方程的解均形如 \(x\equiv r\pmod{q}\) 且 \(x\ge r\) 的形式。

分开考虑前半部分和后半部分,对于前半部分,显然是 ExCRT 的形式。

对于后半部分,可以化为 \(x\ge\max r_i\),令 \(\max r_i=x_0\),放到最后考虑。

考虑使用 ExCRT 解决前半部分,令前 \(i\) 个方程组的解为 \(x\equiv P_i\pmod{Q_i}\),有 \(P_0=0,Q_0=1\)。

但是这里出现一个问题,那就是 \(P_i,Q_i\) 可能很大,但是这里其实没必要使用高精度,要怎么处理这种情况呢?

因为以上方程的解 \(x\equiv r\pmod{q}\) 中,\(q\) 均小于 \(10^7\),所以不需要担心这部分。

考虑这样一种情况:\(Q_{i-1}>10^9\),而再合并进 \(x\equiv r_i\pmod{q_i}\) 可能会让 \(Q_i\) 超出 long long 能够表示的范围。

这时其实不需要再合并了,只需要判断 \(P_{i-1}\) 是否满足第 \(i\) 个方程即可。因为若不满足,合并后 \(x\) 必然会至少增加一倍的 \(Q_{i-1}\),这就超出了 \(10^9\) 的范围,从而可以直接输出无解。

最后,当方程成功合并完之后,\(Q_n\) 可能不是真实值,但是当 \(Q_n\le 10^9\) 时必然是真实值。

此时可以再考虑 \(x_0\),真实的解应该为 \(x=\left\lceil\frac{x_0-P_n}{Q_n}\right\rceil\cdot Q_n+P_n\)。

若 \(Q_n> 10^9\),则必然要满足 \(P_n\ge x_0\),否则无解。

据此写出代码,复杂度 \(\mathcal{O}\left(\sum_{i=1}^{n}\left(\sqrt{g_i}+\log g_i\right)\right)\):

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath> #define Fail return puts("Impossible"), 0
#define mp std::make_pair typedef long long LL;
typedef std::pair<int, int> pii;
const int MG = 10000005, MS = 3175;
const int U = 1e9; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } template<typename T>
T exgcd(T a, T b, T &x, T &y) {
if (!b) return x = 1, y = 0, a;
int d = exgcd(b, a % b, y, x);
return y -= a / b * x, d;
} int buk[MG], stk[MS];
inline int BSGS(int a, int b, int m) {
int S = sqrt(m - 1) + 1;
int A = 1, f = -1, t = 0;
for (int i = 0; i < S; ++i) {
buk[stk[++t] = (LL)b * A % m] = i;
A = (LL)A * a % m;
}
int C = 1;
for (int i = 1; !~f && i <= S; ++i)
if (~buk[C = (LL)C * A % m])
f = i * S - buk[C];
while (t) buk[stk[t--]] = -1;
return f;
} inline pii ExBSGS(int a, int b, int m) {
int o = 0, A = 1 % m, d = 1, nd, x, y;
while (1) {
if (d == (nd = gcd((LL)A * a % m, m))) break;
if (A == b) return mp(o, -1);
++o, A = (LL)A * a % m, d = nd;
}
if (b % d) return mp(-1, -1);
m /= d, b /= d, A /= d;
exgcd(A, m, x, y);
b = (LL)b * (x + m) % m;
x = BSGS(a, b, m);
if (!~x) return mp(-1, -1);
y = BSGS(a, 1 % m, m);
return mp(x % y + o, y);
} inline bool Combine(LL &a1, LL &m1, LL a2, LL m2) {
LL k1, k2, g = exgcd(m1, m2, k1, k2);
if ((a2 - a1) % g) return 0;
a1 += (k1 * ((a2 - a1) / g) % m2 + m2) * m1 % (m1 / g * m2);
return a1 %= m1 *= m2 / g, 1;
} const int MN = 1005; int N;
int k[MN], r[MN], g[MN];
int x[MN], q[MN], X, MaxX; int main() {
memset(buk, -1, sizeof buk), X = -1;
scanf("%d", &N);
for (int i = 1; i <= N; ++i) {
scanf("%d%d%d", &k[i], &g[i], &r[i]);
pii ans = ExBSGS(k[i] % g[i], r[i] % g[i], g[i]);
x[i] = ans.first, q[i] = ans.second;
if (!~x[i]) Fail;
if (!~q[i]) X = x[i];
MaxX = std::max(MaxX, x[i]);
}
if (~X) {
for (int i = 1; i <= N; ++i) {
if (~q[i] && (X < x[i] || (X - x[i]) % q[i])) Fail;
if (!~q[i] && X != x[i]) Fail;
}
return printf("%d\n", X), 0;
}
LL P = 0, Q = 1;
for (int i = 1; i <= N; ++i) {
if (Q > U && (P - x[i]) % q[i]) Fail;
if (Q <= U && !Combine(P, Q, x[i] % q[i], q[i])) Fail;
}
if (P < MaxX) P += ((MaxX - P - 1) / Q + 1) * Q;
if (P > U) Fail;
printf("%lld\n", P);
return 0;
}

洛谷 P5345: 【XR-1】快乐肥宅的更多相关文章

  1. 洛谷 P1271 聚会的快乐(树状dp)

    题目描述 你要组织一个由你公司的人参加的聚会.你希望聚会非常愉快,尽可能多地找些有趣的热闹.但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵.给定N个人(姓名,他幽默的系数,以及他上司的名字) ...

  2. 洛谷 P5706 【深基2.例8】再分肥宅水

    题目连接: P5706 [深基2.例8]再分肥宅水 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 我提交的: 1 #include<iostream> 2 #inclu ...

  3. 洛谷$P4040\ [AHOI2014/JSOI2014]$宅男计划 贪心

    正解:三分+贪心 解题报告: 传送门$QwQ$ 其实很久以前的寒假就考过了,,,但那时候$gql$没有好好落实,就只写了个二分,并没有二分套三分,就只拿到了$70pts$ #include <b ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷1352 CODEVS1380 没有上司的舞会

    洛谷的测试数据貌似有问题,4个点RE不可避 CODEVS可AC —————— 10分钟后追记:在洛谷把数组范围开到10000+就过了 —————— 题目描述 Description Ural大学有N个 ...

  6. BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...

  7. 洛谷 p1352 没有上司的舞会 题解

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  8. 洛谷 P4592: bzoj 5338: [TJOI2018]异或

    题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...

  9. 洛谷P1331海战

    题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线. 不幸的是因为种种原因,国防海军部仅有很少的 ...

随机推荐

  1. 【技术博客】nginx服务器的https协议实现

    在本学期软件工程的Alpha和Beta阶段,我们的服务器部署都是使用基础的http协议,http在网络路由间的信息转发都为明文,这对我们网站的账户密码登录来说很不安全,因此在Gamma阶段我们实现了h ...

  2. 透彻的掌握 Spring 中@transactional 的使用

    事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编码式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...

  3. 解决wireshark抓包校验和和分片显示异常

    问题描述: 在使用wireshark抓取报文时,发现从10.81.2.92发过来的报文绝大部分标记为异常报文(开启IPv4和TCP checksum) 分析如下报文,发现http报文(即tcp pay ...

  4. sublime text 开发记录贴

    1.展示信息有两种: self.view.show_popup('hello'), 这个好看点. sublime.status_message('ssss')    sublime.error_mes ...

  5. 桥接(Bridge)模式

    桥接模式又称为柄体模式或接口模式.桥接模式的用意就是"将抽象化与实现化解耦,使得二者可以独立变化". 抽象化: 存在于多个实体中的共同的概念性联系,就是抽象化.作为一个过程,抽象化 ...

  6. VUE控件 VueTreeselect 参数options的数据转换

    VueTreeselect 控件 <Treeselect :options="options" :normalizer="normalizer" plac ...

  7. Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】

    作者QQ:(648437169) 点击下载➨Delphi支付宝支付             支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...

  8. 14. Scala使用递归的方式去思考,去编程

    14.1 基本介绍 -Scala饰运行在Java虚拟机(Java Virtual Machine)之上,因此具有如下特点 1) 轻松实现和丰富的Java类库互联互通 2) 它既支持面向对象的编程方式, ...

  9. 近3年常考的Spring面试题及答案

    1. 一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spr ...

  10. DELL OptiPlex 7050M黑苹果纪录

    准备工作: 主机:OptiPlex 7050 Micro Desktop Computer 镜像:黑果小兵 macOS Catalina 10.15.1 安装过程: 大体的安装过程,就Dell品牌而言 ...