拓展欧几里得

1.拓展欧的用处:

求解方程 \(ax + by == m\) 的一组解

2.拓展欧的一般性条件:

对于方程\(ax + by = m\),当 \(gcd(a, b)\) 是 m 的整数倍时必定有解

3.求解:

\(d = gcd(a, b)\),则特解为 \( \begin{cases} x = x_0 + \frac{d}{m} \quad\\ y = y_0 + \frac{d}{m} \quad\\ \end{cases} \)
通解\( \begin{cases} x = x_0 + k*\frac{b}{d} \quad\\ y = y_0 - k*\frac{a}{d} \quad\\ \end{cases} \)

4.应用方法:

求解一次同余方程 \(ax≡b(mod m)\)
转化:\(ax = km + b\)
\(k^, = -k\)
即得:\(ax + k^,m = b\)

5.例题Lunatic Never Content

题目描述

现在有一个数组 \(a\),和 \(n\) 个非负整数,定义 \(f(a,x)=[a_1\bmod x,a_2\bmod x,\dots,a_n\bmod x]\),其中 \(x\) 为正整数。现要你找到最大的 \(x\),使得 \(f(a,x)\) 是回文的。

这里,\(a \bmod x\) 的含义为 \(a\) 除以 \(x\) 得到的余数。

我们认为一个数组是回文的,当且仅当从前往后读得到的结果和从后往前读得到的结果完全相同。换句话说,一个长度为 \(n\) 的数组 \(a\) 是回文的,当且仅当 \(\forall 1\leq i \leq n\),有 \(a_i=a_{n-i+1}\)

输入格式

第一行一个整数 \(t(1 \leq t \leq 10^5)\),代表测试数据的组数。

对于每一组测试数据:

第一行一个整数 \(n(1 \leq n \leq 10^5)\),代表数组 \(a\) 的长度。

第二行共 \(n\) 个数,以空格隔开,对于 \(1\leq i \leq n\),第 \(i\) 个数代表 \(a_i\)

数据保证 \(\sum n \leq 10^5\)

输出格式

对于每一组测试用例,输出最大的 \(x\) ,使得 \(f(a,x)\) 是回文的。如果 \(x\) 可以为无穷大,输出 \(0\) 来代替。

样例 #1

样例输入 #1

4
2
1 2
8
3 0 1 2 0 3 2 1
1
0
3
100 1 1000000000

样例输出 #1

1
2
0
999999900

分析:

要实现回文位置的同余,即\(a≡b(mod x)\),要求$ x 则当且仅当 x 为 gcd(a, b)$的整数倍时才满足

实现:

#include <bits/stdc++.h>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x)
#define endl '\n'
#define INF LONG_LONG_MAX
#define int long long
#define Lson u << 1, l, mid
#define Rson u << 1 | 1, mid + 1, r
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 2000010, MOD = 1e9 + 7;
const double EPS = 1e-6;
typedef pair<int, int> PII;
int T;
int n;
int a[N];
int res;
void solve()
{
    res = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    for (int i = 1; i <= n / 2; i++)
    {
        int tmp = abs(a[i] - a[n - i + 1]);
        res = __gcd(res, tmp);
    }

    cout << res << endl;
}
signed main()
{
    FAST;
    T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
posted @ 2023-05-20 21:58  347Foricher  阅读(52)  评论(0)    收藏  举报