Comet OJ - Contest # 10 fish big splash derived exgcd +

Exam time launch, but forgot to $ exgcd $ ye seek, success explosive egg ~

Here is an template is the smallest positive integer solutions:

ll solve(ll A,ll B,ll C) 
{    
    ll x,y,g,b,ans; 
    gcd = exgcd(A,B,x,y);                 
    if(C%gcd!=0) return -1;        
    x*=C/gcd,B/=gcd; 
    if(B<0) B=-B;   
    ans=x%B;      
    if(ans<=0) ans+=B;  
    return ans;        
} 

It is probably the case. 

Talk about the title:

Questions can be converted to seek $ \ frac {ans (ans + 1)} {2} \ mod n = 0 $ minimum $ ans $.
The expression transforming it, i.e. $ ans (ans + 1) = 2n \ times Y $, Y $ where $ is an integer of
readily available ANS $ $ and $ ans + 1 $ are relatively prime, so 2N $ $ each a different prime factors can contribute to $ ans, ans + 1 $ in a.
and $ 10 ^ {12} $ only numbers up to within less than a dozen different prime factors nature, can be enumerated subsets.
consider enumerate $ $ a $ and B $, $ a order \ times x = ans, B \ times y = ans + 1 $.
it needs to meet $ Ax-By = -1, gcd (x, y) = 1 $
but in fact we found $ gcd (x, y) = 1 $ it is not sentenced, because the position if equality holds, then $ gcd (x, y) $ is necessarily $ 1 $.
so, we just need to find $ Ax-By = -1 $ $ x $ smallest positive integer solution on the line . of
this can be $ exgcd $ immediate requirements, but there are some details that need attention:

  1. $ A, B $ $ need to be greater than $ 0.
  2. We want to find $ x $, $ y $ in the end is so much we do not care about, direct disregard out just fine.

Code: 

#include <cstdio>  
#include <vector> 
#include <algorithm>   
#define N 1000006 
#define inf 100000000000000000
#define ll long long 
#define LL long long
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll ans=exgcd(b,a%b,x,y);
    ll tmp=x;
    x=y,y=tmp-a/b*y;
    return ans;
}         
vector<ll>v;   
int tot; 
int prime[N],is[N];    
void init() 
{ 
    int i,j; 
    for(i=2;i<N;++i) 
    {
        if(!is[i]) prime[++tot]=i;         
        for(j=1;j<=tot&&1ll*prime[j]*i<1ll*N;++j) 
        {
            is[prime[j]*i]=1; 
            if(i%prime[j]==0) break;    
        }
    }    
}
ll solve(ll A,ll B) 
{    
    ll x,y,g,b,ans; 
    g = exgcd(A,B,x,y);                 
    if(-1%g) return inf;        
    x*=-1/g,y*=g;    
    B/=g; 
    if(B<0) B=-B;   
    ans=x%B;      
    if(ans<=0) ans+=B;  
    return ans*A; 
} 
int main() 
{ 
    // setIO("input");  
    init(); 
    int T,i,j; 
    scanf("%d",&T); 
    while(T--)
    {
        ll n,h,answer=inf; 
        scanf("%lld",&n),h=n;
        for(i=1;i<=tot;++i) 
        {
            if(h%prime[i]==0) 
            { 
                ll kk=1;    
                while(h%prime[i]==0) 
                { 
                    h/=prime[i];   
                    kk*=prime[i];    
                }      
                v.push_back(kk);    
            }       
        }
        if(h) v.push_back(h);                  
        int len=v.size();    
        for(i=0;i<(1<<len);++ i) // enumerate all subsets
        {  
            ll tmp=1; 
            for(j=0;(1<<j)<=i;++j) 
            {  
                if(i&(1<<j)) 
                    tmp*=v[j];         
            }
            ll A=tmp,B=2*n/tmp;     
            answer=min(answer,min(solve(A,B),solve(B,A)));  
        }
        printf("%lld\n",answer); 
        v.clear();    
    }
    return 0; 
}

  

Guess you like

Origin www.cnblogs.com/guangheli/p/11481512.html