結果
問題 | No.1255 ハイレーツ・オブ・ボリビアン |
ユーザー | 👑 Kazun |
提出日時 | 2022-06-05 03:37:03 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,145 ms / 2,000 ms |
コード長 | 4,623 bytes |
コンパイル時間 | 2,446 ms |
コンパイル使用メモリ | 208,524 KB |
実行使用メモリ | 5,952 KB |
最終ジャッジ日時 | 2024-09-21 03:59:09 |
合計ジャッジ時間 | 7,624 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 3 ms
5,376 KB |
testcase_05 | AC | 6 ms
5,376 KB |
testcase_06 | AC | 6 ms
5,376 KB |
testcase_07 | AC | 6 ms
5,376 KB |
testcase_08 | AC | 523 ms
5,700 KB |
testcase_09 | AC | 549 ms
5,952 KB |
testcase_10 | AC | 549 ms
5,820 KB |
testcase_11 | AC | 542 ms
5,584 KB |
testcase_12 | AC | 551 ms
5,708 KB |
testcase_13 | AC | 50 ms
5,752 KB |
testcase_14 | AC | 1,145 ms
5,712 KB |
testcase_15 | AC | 518 ms
5,948 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; using ll=long long; struct Modulo{ int64_t a; int n; public: // 初期化 Modulo(): a(0), n(1){} Modulo(int64_t a_, int n_){ if (n_>0) a=(a_%n_+n_)%n_, n=n_; else a=0LL, n=0; } // マイナス元 Modulo operator-() const {return Modulo(-a,n);} // 加法 Modulo& operator+=(const Modulo &y){ assert (n==y.n); if ((a+=y.a)>=n) a-=n; return *this; } Modulo& operator+=(const int64_t &y){return (*this)+=Modulo(y,n);} friend Modulo operator+(const Modulo &x, const Modulo &y) {return Modulo(x)+=y;} friend Modulo operator+(const Modulo &x, const int64_t &a) {return x+Modulo(a,x.n);} friend Modulo operator+(const int64_t &a, const Modulo &x) {return Modulo(a,x.n)+x;} // 減法 Modulo& operator-=(const Modulo &y){ assert (n==y.n); if ((a+=(n-y.a))>=n) a-=n; return *this; } Modulo& operator-=(const int64_t &y){return (*this)-=Modulo(y,n);} friend Modulo operator-(const Modulo &x, const Modulo &y) {return Modulo(x)-=y;} friend Modulo operator-(const Modulo &x, const int64_t &a) {return x-Modulo(a,x.n);} friend Modulo operator-(const int64_t &a, const Modulo &x) {return Modulo(a,x.n)-x;} // 乗法 Modulo& operator*=(const Modulo &y){ assert (n==y.n); (a*=y.a)%=n; return *this; } Modulo& operator*=(const int64_t &y){return (*this)*=Modulo(y,n);} friend Modulo operator*(const Modulo &x, const Modulo &y) {return Modulo(x)*=y;} friend Modulo operator*(const Modulo &x, const int64_t &a) {return x*Modulo(a,x.n);} friend Modulo operator*(const int64_t &a, const Modulo &x) {return Modulo(a,x.n)*x;} // 除法 Modulo& operator/=(const Modulo &y){ assert (n==y.n); return (*this)*=y.inverse(); } Modulo& operator/=(const int64_t &y){return (*this)/=Modulo(y,n);} friend Modulo operator/(const Modulo &x, const Modulo &y) {return Modulo(x)/=y;} friend Modulo operator/(const Modulo &x, const int64_t &a) {return x/Modulo(a,x.n);} friend Modulo operator/(const int64_t &a, const Modulo &x) {return Modulo(a,x.n)/x;} // 退化 Modulo& degenerate(const int m){ assert (n%m==0); a%=m; n=m; return *this; } // モジュラー逆元 bool invertible() const { int64_t x=a, y=n; while (y) swap(x=x%y,y); return x==1; } Modulo inverse() const{ int64_t s=1, t=0; int64_t x=a, y=n; while (y){ auto q=x/y; swap(x-=q*y,y); swap(s-=q*t,t); } assert(x==1); return Modulo(s,n); } // 比較 friend bool operator==(const Modulo &x, const Modulo &y) {return x.a==y.a;} friend bool operator==(const Modulo &x, const int64_t &a) {return (x.a-a)%x.n==0;} friend bool operator==(const int64_t &a, const Modulo &x) {return (a-x.a)%x.n==0;} friend bool operator!=(const Modulo &x, const Modulo &y) {return x.a!=y.a;} friend bool operator!=(const Modulo &x, const int64_t &a) {return (x.a-a)%x.n!=0;} friend bool operator!=(const int64_t &a, const Modulo &x) {return (a-x.a)%x.n!=0;} // 入力 friend istream &operator>>(istream &is, Modulo &x) { int64_t b; int m; is >> b >> m; x=Modulo(b,m); return (is); } // 出力 friend ostream &operator<<(ostream &os, const Modulo &x) { return os << x.a << " (mod " << x.n << ")";} }; //離散対数 int64_t Discrete_Logarithm(Modulo X, Modulo Y){ assert(X.n==Y.n); int64_t f,g,m; Modulo R(1,X.n); // Step 1: 可逆元の累乗に持ち込む for (f=0; (g=gcd(X.a,X.n))>1; f++){ if (Y.a%g) return (R==Y) ? f: -1; m=X.n/g; R*=X.a/g; R.degenerate(m); X.degenerate(m); Y.a/=g; Y.degenerate(m); } if (X.n==1) return f; Y/=R; // Step 2-a: Baby-Step int64_t t=0; Modulo H(1,X.n); unordered_map<int64_t, int64_t> B; for (; t*t<X.n; t++){ if (B.find(H.a)==B.end()) B[H.a]=t; H*=X; } // Step 2-b: Giant-Step Modulo H_inv=H.inverse(); for (int64_t j=0; j<t; j++){ if (B.find(Y.a)!=B.end()) return f+j*t+B[Y.a]; Y*=H_inv; } return -1; } // 位数 int64_t Order(const Modulo &X){ return (X.invertible()) ? Discrete_Logarithm(X, X.inverse())+1: -1; } int main(){ int T; cin >> T; for (int t=0; t<T; t++){ int N; cin >> N; cout << Order(Modulo(2,2*N-1)) << "\n"; } }