結果
| 問題 |
No.551 夏休みの思い出(2)
|
| コンテスト | |
| ユーザー |
minami
|
| 提出日時 | 2019-04-01 16:00:15 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 65 ms / 4,000 ms |
| コード長 | 3,934 bytes |
| コンパイル時間 | 1,584 ms |
| コンパイル使用メモリ | 171,800 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-11-25 05:51:00 |
| 合計ジャッジ時間 | 5,005 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 47 |
ソースコード
#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif
#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }
// 累乗
// O(log e)
// mod^2 が long long の最大値より大きければオーバーフローするので掛け算に modmul を使う
long long modpow(long long a, long long e, long long mod) {
long long res = 1;
while (e > 0) {
if (e & 1)res = res * a % mod; // modmul(res, a, mod);
a = a * a % mod; // modmul(a, a, mod);
e >>= 1;
}
return res;
}
// 逆元
// O(log mod)
long long modinv(long long a, long long mod) {
return modpow(a, mod - 2, mod);
}
// Legendre symbol
// a|p なら 0
// a が平方剰余なら 1
// a が平方非剰余なら -1
int legendre(long long a, long long p) {
long long l = modpow(a, (p - 1) / 2, p);
return l == p - 1 ? -1 : l;
}
long long modsqrt(long long a, long long p) {
int l = legendre(a, p);
if (l != 1)return l;
long long S = 0, Q = p - 1;
while (!(Q & 1)) {
S++;
Q >>= 1;
}
long long z = 1;
while (legendre(z, p) == 1)z++;
long long M = S;
long long c = modpow(z, Q, p);
long long t = modpow(a, Q, p);
long long R = modpow(a, (Q + 1) / 2, p);
while (t != 1) {
for (int i = 1; i < M; i++) {
if (modpow(t, 1 << i, p) != 1)continue;
long long b = modpow(c, 1 << (M - i - 1), p);
M = i;
c = b * b % p;
t = t * b % p * b % p;
R = R * b % p;
break;
}
}
return R;
}
struct DModInt {
static int kMod;
unsigned x;
DModInt() :x(0) {}
DModInt(signed x_) { x_ %= kMod; if (x_ < 0)x_ += kMod; x = x_; }
DModInt(signed long long x_) { x_ %= kMod; if (x_ < 0)x_ += kMod; x = x_; }
int get()const { return (int)x; }
DModInt &operator+=(DModInt m) { if ((x += m.x) >= kMod)x -= kMod; return *this; }
DModInt &operator-=(DModInt m) { if ((x += kMod - m.x) >= kMod)x -= kMod; return *this; }
DModInt &operator*=(DModInt m) { x = (unsigned long long)x*m.x%kMod; return *this; }
DModInt &operator/=(DModInt m) { return *this *= m.inverse(); }
DModInt operator+(DModInt m)const { return DModInt(*this) += m; }
DModInt operator-(DModInt m)const { return DModInt(*this) -= m; }
DModInt operator*(DModInt m)const { return DModInt(*this) *= m; }
DModInt operator/(DModInt m)const { return DModInt(*this) /= m; }
DModInt operator-()const { return DModInt(kMod - x); }
bool operator==(DModInt m)const { return x == m.x; }
bool operator!=(DModInt m)const { return x != m.x; }
DModInt inverse()const {
signed a = x, b = kMod, u = 1, v = 0;
while (b) {
signed t = a / b;
a -= t * b; swap(a, b);
u -= t * v; swap(u, v);
}
if (u < 0)u += kMod;
return DModInt(u);
}
};
int DModInt::kMod = MOD;
ostream &operator<<(ostream &os, const DModInt &m) { return os << m.x; }
istream &operator>>(istream &is, DModInt &m) { signed long long s; is >> s; m = DModInt(s); return is; };
DModInt pow(DModInt a, unsigned long long k) {
DModInt r = 1;
while (k) {
if (k & 1)r *= a;
a *= a;
k >>= 1;
}
return r;
}
using mint = DModInt;
signed main() {
cin.tie(0);
ios::sync_with_stdio(false);
int p, r, q; cin >> p >> r >> q;
mint::kMod = p;
rep(_, 0, q) {
mint a, b, c; cin >> a >> b >> c;
mint A = (b*b / 4 / a - c) / a;
int X = modsqrt(A.get(), p);
if (X == -1) {
cout << X << endl;
}
else {
mint x = (mint(X) - b * modinv(2, p) / a);
mint y = (mint(-X) - b * modinv(2, p) / a);
if (x.get() > y.get())swap(x, y);
if (X == 0)
cout << x << endl;
else
cout << x << " " << y << endl;
}
}
return 0;
}
minami