ACL Contest1 B- Sum is Multiple 数论,EXGCD
ACL Contest1 B- Sum is Multiple 数论,EXGCD
题意
求最小的\(k\)满足 \(2n | k(k+1)\)
\[1\leq n \leq 1e15
\]
分析
设\(k\)的质因子集合\(P_1\),\(k+1\)的质因子集合\(P_2\),\(2n\)的质因子集合\(P_n\)
对于任意\(x \in P_n\) ,\(=>\) \(x \in P_1 \quad or \quad x \in P_2\)
令\(A = \prod x(x \in P_1 \bigcap P_n)\),\(B = \prod x(x \in P_2 \bigcap P_n)\)
由于\(gcd(k,k+1)=1\) \(AB = 2n\)
\(k = a \cdot A,k+1=b\cdot B\)
即\(-a\cdot A + b\cdot B = 1\)
于是枚举\(AB\)跑EXGCD即可。
当然也可以转化为同余式
\[k \equiv 0 (mod A)\\
k \equiv -1(mod B)
\]
跑crt即可
代码
#include<bits/stdc++.h>
#define eps 1e-4
#define equals(a,b) (fabs(a - b) < eps)
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
typedef long long ll;
ll rd(){
ll x = 0;
int f =1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll ai[5], bi[5];
ll mul(ll a, ll b, ll mod){
ll res = 0;
while (b > 0)
{
if (b & 1) res = (res + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return res;
}
ll exgcd(ll a, ll b, ll& x, ll& y){
if (b == 0) { x = 1; y = 0; return a; }
ll gcd = exgcd(b, a % b, x, y);
ll tp = x;
x = y; y = tp - a / b * y;
return gcd;
}
ll gcd(ll a,ll b){
return b == 0 ? a : gcd(b,a % b);
}
ll excrt(){
ll x, y, k;
ll M = bi[1], ans = ai[1];
for (int i = 2; i <= 2; i++)
{
ll a = M, b = bi[i], c = (ai[i] - ans % b + b) % b;
ll gcd = exgcd(a, b, x, y), bg = b / gcd;
if (c % gcd != 0) return -1;
x = mul(x, c / gcd, bg);
ans += x * M;
M *= bg;
ans = (ans % M + M) % M;
}
return (ans % M + M) % M == 0 ? M : (ans % M + M) % M;
}
int main(){
ai[1] = 0;
ai[2] = -1;
ll n = rd();
ll k = 1e18;
n <<= 1;
for(ll i = 1;i * i <= n;i++){
if(n % i) continue;
if(gcd(i,n / i) == 1) {
bi[1] = i;
bi[2] = n / i;
k = min(k,excrt());
bi[1] = n / i;
bi[2] = i;
k = min(k,excrt());
}
}
cout << k;
}