結果
| 問題 |
No.2589 Prepare Integers
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-12-06 20:21:12 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 3,848 bytes |
| コンパイル時間 | 6,467 ms |
| コンパイル使用メモリ | 255,352 KB |
| 最終ジャッジ日時 | 2025-02-18 08:43:47 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 WA * 1 |
| other | AC * 5 WA * 19 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
struct Fast {
Fast() {
std::cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << setprecision(10);
}
} fast;
#define all(a) (a).begin(), (a).end()
#define rep(i, a, b) for (int(i) = (a); (i) < (int)(b); (i)++)
#define rrep(i, a, b) for (int(i) = (int)(b)-1; (i) >= (a); (i)--)
using vi = vector<int>;
using ll = long long;
using vl = vector<ll>;
ll safe_mod(ll a, ll b) {
ll c = a % b;
return c < 0 ? c + b : c;
}
ll ext_gcd(ll a, ll b, ll& x, ll& y) {
for (ll u = y = 1, v = x = 0; a;) {
ll q = b / a;
swap(x -= q * u, u);
swap(y -= q * v, v);
swap(b -= q * a, a);
}
return b;
}
const ll A_MAX = 1e9;
int lg;
ll k;
vl powk, basis, cnt, msd;
bool is_prime;
ll op(ll a, ll b) {
if (k == 2) return a ^ b;
ll ret = 0, pow = 1;
while (a | b) {
ret += (a + b) % k * pow;
a /= k;
b /= k;
pow *= k;
}
return ret;
}
ll op_pow(ll a, ll n) {
if (k == 2) return n & 1 ? a : 0;
if (n == 0) return 0;
n = safe_mod(n, k);
ll ret = 0, pow = 1;
while (a) {
ret += safe_mod(a % k * n, k) * pow;
a /= k;
pow *= k;
}
return ret;
}
void query1(ll x) {
if (k == 2) {
rrep(i, 0, lg) {
if (x >> i) {
if (basis[i] == 0) {
basis[i] = x;
msd[i] = 1;
break;
}
x ^= basis[i];
}
}
} else if (is_prime) {
rrep(i, 0, lg) {
if (x / powk[i]) {
if (basis[i] == 0) {
ll s, t;
ext_gcd(x / powk[i], k, s, t);
basis[i] = op_pow(x, s);
msd[i] = 1;
break;
}
x = op(x, op_pow(basis[i], -(x / powk[i])));
}
}
} else {
vl a{x};
rrep(i, 0, lg) {
ll g = msd[i];
vl v(a.size()), prod(a.size() + 1);
rep(j, 0, a.size()) {
ll u = a[j] / powk[i];
ext_gcd(g, u, prod[j], v[j]);
g = g * prod[j] + u * v[j];
prod[j] = safe_mod(prod[j], k);
v[j] = safe_mod(v[j], k);
}
rrep(j, 1, a.size()) prod[j - 1] = safe_mod(prod[j - 1] * prod[j], k);
ll t = op_pow(basis[i], prod[0]);
prod[a.size()] = 1;
rep(j, 0, a.size()) t = op(t, op_pow(a[j], v[j] * prod[j + 1] % k));
rep(j, 0, a.size()) a[j] = op(a[j], op_pow(t, -a[j] / powk[i] / g));
a.push_back(op(basis[i], op_pow(t, -msd[i] / g)));
if (g != k) {
basis[i] = t;
msd[i] = g;
}
}
}
rep(i, 0, lg) cnt[i + 1] = cnt[i] * (k / msd[i]);
}
void query2(ll x) {
if (x > cnt[lg]) {
cout << -1 << "\n";
return;
}
x--;
ll ans = 0;
rrep(i, 0, lg) {
if (basis[i] == 0) continue;
ll u = msd[i];
ll v = ans / powk[i];
ans = op(ans, op_pow(basis[i], x / cnt[i] - v / u));
x %= cnt[i];
}
cout << ans << "\n";
}
void query3(ll x) {
x++;
ll ans = 0, y = 0;
rrep(i, 0, lg) {
if (basis[i] == 0) {
ll u = x / powk[i] % k, v = y / powk[i] % k;
if (u == v) continue;
if (u > v) ans += cnt[i];
break;
} else {
ll d = y / powk[i] % k;
ll u = msd[i];
y = op(y, op_pow(basis[i], -(d / u)));
d %= u;
ll v = x / powk[i] % k - d;
ans += (v + u - 1) / u * cnt[i];
if (v % u) break;
y = op(y, op_pow(basis[i], v / u));
}
}
cout << ans << "\n";
}
int main() {
int q;
cin >> k >> q;
is_prime = true;
for (ll d = 2; d * d <= k; d += (d & 1) + 1)
if (!(k % d)) {
is_prime = false;
break;
}
powk = vl();
for (ll p = 1; p <= A_MAX; p *= k) powk.push_back(p);
lg = (int)powk.size();
basis = vl(lg, 0);
msd = vl(lg, k);
cnt = vl(lg + 1);
cnt[0] = 1;
while (q--) {
int t;
ll x;
cin >> t >> x;
if (t == 1) query1(x);
if (t == 2) query2(x);
if (t == 3) query3(x);
}
}