题目链接
204. 表达整数的奇怪方式
给定 \(2n\) 个整数 \(a_1,a_2,…,a_n\) 和 \(m_1,m_2,…,m_n\),求一个最小的非负整数 \(x\),满足 \(\forall i \in [1,n],x \equiv m_i(mod\ a_i)\)。
输入格式
第 \(1\) 行包含整数 \(n\)。
第 \(2…n+1\) 行:每 \(i+1\) 行包含两个整数 \(a_i\) 和 \(m_i\),数之间用空格隔开。
输出格式
输出最小非负整数 \(x\),如果 \(x\) 不存在,则输出 \(-1\)。
如果存在 \(x\),则数据保证 \(x\) 一定在 \(64\) 位整数范围内。
数据范围
\(1 \le a_i \le 2^{31}-1\),
\(0 \le m_i < a_i\)
\(1 \le n \le 25\)
输入样例:
2
8 7
11 9
输出样例:
31
解题思路
扩展中国剩余定理
假设已经求出了前 \(k-1\) 个方程的一个特解 \(x\),设 \(m=lcm(a_1,a_2,\dots,a_{k-1})\),则其通解为 \(x+k\times m\)(其中 \(k\) 为整数),现在需要考虑第 \(k\) 个方程,即要找到这样的一个 \(t\),使得 \(x+t\times m\equiv b_k(\bmod a_k)\),即 \(t\times m\equiv b_k-x(\bmod a_k)\),利用扩展欧几里得即可求解这样的 \(t\),在利用扩欧通解更新 \(x\),同时更新 \(m\),最后的 \(x\) 即为答案
- 时间复杂度:\(O(mlogn)\)
代码
// Problem: 表达整数的奇怪方式
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/206/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include <bits/stdc++.h>
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=30;
int n,a[N],b[N];
LL res;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1,y=0;
return a;
}
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
bool f=true;
res=b[1];
LL lcm=a[1];
for(int i=2;i<=n;i++)
{
LL x,y;
LL d=exgcd(lcm,a[i],x,y);
if((b[i]-res)%d!=0)
{
f=false;
break;
}
x*=(b[i]-res)/d;
LL t=a[i]/d;
x=(x%t+t)%t;
res+=lcm*x;
lcm=(LL)a[i]/d*lcm;
}
if(f)
printf("%lld",(res%lcm+lcm)%lcm);
else
puts("-1");
return 0;
}
标签:le,表达,204,int,LL,整数,return,define
From: https://www.cnblogs.com/zyyun/p/16897764.html