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:
- $ A, B $ $ need to be greater than $ 0.
- 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; }