zoukankan      html  css  js  c++  java
  • ACL Contest1 B- Sum is Multiple 数论,EXGCD

    ACL Contest1 B- Sum is Multiple 数论,EXGCD

    题意

    求最小的(k)满足 (2n | k(k+1))

    [1leq 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 igcap P_n)),(B = prod x(x in P_2 igcap P_n))

    由于(gcd(k,k+1)=1) (AB = 2n)

    (k = a cdot A,k+1=bcdot B)

    (-acdot A + bcdot 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;
    }
    
  • 相关阅读:
    LintCode-35.翻转链表
    LintCode-159.寻找旋转排序数组中的最小值
    LintCode-73.前序遍历和中序遍历树构造二叉树
    LintCode-9.Fizz Buzz 问题
    NOI 2018 归程 (Kruskal重构树)
    模板 NTT 快速数论变换
    模板 FFT 快速傅里叶变换
    BZOJ 3510 首都 (LCT)
    BZOJ 4530 [BJOI2014]大融合 (LCT)
    BZOJ 3282 Link Cut Tree (LCT)
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14491978.html
Copyright © 2011-2022 走看看