Loading

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;
}
posted @ 2021-03-06 19:39  MQFLLY  阅读(80)  评论(0编辑  收藏  举报