comet#10 C

//枚举 2n 的质因子a ,2n/a = b,  ap - bq = 1, 找到 bq(min)

#include<bits/stdc++.h>
const int MA = 1e6+100;
typedef long long ll;
int t, vis[MA],pri[MA],prinum,cnt;
ll n,fac[50];
using namespace std;

void exgcd(ll a, ll b, ll& d, ll& x, ll& y){
    if(!b) { x = 1, y = 0; d = a;}
    else { exgcd(b, a%b, d, y, x);  y -= x*(a/b);}
}
void init(){// 素数表
    for(int i = 2; i <= MA-100; i++)
    {
        if(!vis[i]) pri[++prinum] = i;
        for(int j = 1; j <= prinum && pri[j]*i <= MA-100; j++) {
            vis[pri[j]*i] = 1;
            if(i % pri[j] == 0) break;
        }
    }
}
ll calc(ll a, ll b){
    if(b == 1) return a-1;
    ll d,x,y;
    exgcd(a, b, d, x, y);
    //x = (x%b+b)%b;
    if(a*x <= 1) x += b;// bq >= 0, so ap=bq+1 ap >=1  通解x=x0+kb, y = y0-ka
    return a*x-1;
}
ll dfs(ll num, ll a, ll b){
    if(num > cnt) return calc(a, b);
    return min(dfs(num+1, a*fac[num], b), dfs(num+1, a, b*fac[num]));
}
int main(){
    init();
    cin>>t;
    while(t--) {
        cin>>n;
        n <<= 1;
        cnt = 0;
        for(int i = 1; i <= prinum; i++) {
            if(n % pri[i]) continue;
            fac[++cnt] = 1;
            while(n%pri[i] == 0)
            {
                n /= pri[i];
                fac[cnt] *= pri[i];
            }
        }
        if(n > 1)    fac[++cnt] = n;
        ll ans = dfs(1,1,1);
        cout<< ans <<endl;
    }
    return 0;    
}/*
5
2
4
6
8
10

样例输出 1

3
7
3
15
4
*/

 

转载于:https://www.cnblogs.com/163467wyj/p/11503683.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值