試験時間の打ち上げが、$のexgcdの$がたに忘れてしまったが、成功爆発卵を求めて〜
ここではテンプレートが最小の正の整数解であります:
LL(LLのA、LLのB、LLのC)解く { LLのX、Y、G、Bを、ANS。 GCD = exgcd(A、B、X、Y)。 もし(!C%GCD = 0)リターン-1; X * = C / GCD、B / = GCD。 (B <0)B = -B場合; ANS = X%のB; (ANS <= 0)ANS + = Bであれば、 ANSを返します。 }
それはおそらくケースです。
タイトルについての講演:
質問が$ \ FRAC {ANS(ANS +シークに変換することができる MOD N = 0 $ \ {2} 1)} 最小の$ ANSの$。
それを変換式、即ち$ ANS(ANS + 1)= 2N \回Yの$、$は、の整数であるY $
ANS $ $、容易に入手可能であり、$ ANS + 1 $ 1 $、異なる素因数が$ ANSに寄与することができる$ $各ので2N互いに素である、ANS + 。
そしてダース異なる素因数性質未満以内$ 10 ^ {12} $だけ数値までは、サブセットを挙げることができる。
$ $ $とB $を列挙検討順序を$ \倍のx =アンス、Bの\ Y =アンスは、+ 1 $。回
、それが満たす必要$ AX-ことで= -1、GCD (X、Y)= 1 $
が、実際に、我々は$のGCD(x、y)を見つけ= 1 $ 等式が成立する場合の位置は、その後、$ GCDので、。(x、y)は$は必ずしも$ 1 $で、宣告されていない
ので、私達はちょうどライン上= -1 $ $ X $最小の正の整数解ではAX-$を見つける必要があります。の
これは$ exgcd $即時要件することができますが、注意が必要ないくつかの詳細があります。
- $ A、B $ $を超える$ 0にする必要があります。
- 私たちは、$ xに$を見つけたい、最後に$ yを$はそんなに私たちは、直接無視アウトだけで結構気にしないです。
コード:
#include <cstdioを> する#include <ベクトル> の#include <アルゴリズム> の#define N 1000006 の#define INF 100000000000000000 の#defineは長い長いっ の#define LL長い長 の#define setIO(S)freopenは(S ".IN"、 "R" 、STDIN) 名前空間stdを使用。 (-1,11,11-のB、LL&X、LL&Y)exgcd LL { (B == 0)場合 、{ X = 1、Y = 0 返します。 } LL ANS = exgcd(B、%のB、X、Y)。 LLのTMP = X。 X = Y、Yは、TMP-A / Bの* yを=。 ANSを返します。 } ベクトル<LL> V。 int型のTOT; INTプライム[N]、[N]です。 INITを無効() { 私は、jはint型。 (I = 2の場合、iがNを<。 { もしプライム[++ TOT = I(ある[I]!)。 ため(J = 1; J <= TOT && 1LL *プライム[J] * I <1LL * N; ++ j)は { ある[プライム[J] * I] = 1。 もし(I%、プライム[J] == 0)ブレーク。 } } } (LLのA、LLのB)解決ちゃう { LLのX、Y、G、B、ANS。 G = exgcd(A、B、X、Y)。 IF(-1%G)戻りINF。 X * = - 1 / G、Y * = G。 B / = G。 (B <0)B = -B場合; ANS = X%のB; (ANS <= 0)ANS + = Bであれば、 ANS *のAを返します。 } int型のmain() { // setIO( "入力")。 その中に(); int型T、I、J。 scanf関数( "%のD"、&T)。 (T--)一方 { LL N、H、答え= INF。 scanf関数( "%のLLD"、&n)は、H = N。 用(i = 1; I <= TOT; ++ I) { IF(H%のプライム[I] == 0) { LLのKK = 1。 一方、(時間%プライム[I] == 0) { H / =プライム[I]。 KK * =プライム[i]は、 } v.push_back(KK)。 } } IF(H)v.push_back(H)。 INT LEN = v.size()。 (I = 0; I <(1 << LEN)。 { LL TMP = 1。 用(J = 0、(1 << J)<= I; ++ j)は { IF(I&(1 << J)) TMP * = V [J]。 } LL A = TMP、B = 2 * N / TMP。 答え=分(答え、分((B、A)を解く、(A、B)を解きます))。 } のprintf( "%LLDする\ n"、答え)。 v.clear(); } 0を返します。 }