結果
問題 | No.3102 floor sqrt xor |
ユーザー |
|
提出日時 | 2025-04-11 22:25:19 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 8,122 bytes |
コンパイル時間 | 4,247 ms |
コンパイル使用メモリ | 258,300 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-04-11 22:25:24 |
合計ジャッジ時間 | 5,117 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 30 |
ソースコード
#ifndef HIDDEN_IN_VS // 折りたたみ用 // 警告の抑制 #define _CRT_SECURE_NO_WARNINGS // ライブラリの読み込み #include <bits/stdc++.h> using namespace std; // 型名の短縮 using ll = long long; using ull = unsigned long long; // -2^63 ~ 2^63 = 9e18(int は -2^31 ~ 2^31 = 2e9) using pii = pair<int, int>; using pll = pair<ll, ll>; using pil = pair<int, ll>; using pli = pair<ll, int>; using vi = vector<int>; using vvi = vector<vi>; using vvvi = vector<vvi>; using vvvvi = vector<vvvi>; using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>; using vvvvl = vector<vvvl>; using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>; using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>; using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>; template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>; using Graph = vvi; // 定数の定義 const double PI = acos(-1); int DX[4] = { 1, 0, -1, 0 }; // 4 近傍(下,右,上,左) int DY[4] = { 0, 1, 0, -1 }; int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF; // 入出力高速化 struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp; // 汎用マクロの定義 #define all(a) (a).begin(), (a).end() #define sz(x) ((int)(x).size()) #define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x))) #define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x))) #define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");} #define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順 #define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順 #define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順 #define repe(v, a) for(const auto& v : (a)) // a の全要素(変更不可能) #define repea(v, a) for(auto& v : (a)) // a の全要素(変更可能) #define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索(昇順) #define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素(昇順) #define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て(昇順) #define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去 #define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了 #define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定 // 汎用関数の定義 template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; } template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新(更新されたら true を返す) template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新(更新されたら true を返す) template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); } template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod // 演算子オーバーロード template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; } template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; } template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; } template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; } #endif // 折りたたみ用 #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #ifdef _MSC_VER #include "localACL.hpp" #endif using mint = modint998244353; //using mint = static_modint<(int)1e9 + 7>; //using mint = modint; // mint::set_mod(m); namespace atcoder { inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; } inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; } } using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>; #endif #ifdef _MSC_VER // 手元環境(Visual Studio) #include "local.hpp" #else // 提出用(gcc) inline int popcount(int n) { return __builtin_popcount(n); } inline int popcount(ll n) { return __builtin_popcountll(n); } inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; } inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; } inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; } inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; } #define dump(...) #define dumpel(v) #define dump_math(v) #define input_from_file(f) #define output_to_file(f) #define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す #endif //【整数平方根】O(1) /* * 非負の数 a の平方根の切り捨て値を返す. * * 制約:コンパイラが gcc */ template <class T> T integer_sqrt(T a) { //【備考】 // double 精度だと,N = 622046740405562316 で // (int)sqrt(N) = 788699398 != 788699397 = floor(√N) // となってしまった. return (T)sqrtl((long double)a); } void zikken() { int n = 5000; vi res; repi(k, 1, n) { auto x = integer_sqrt(k); res.push_back(x ^ k); //dump(x ^ k); } uniq(res); //dump(res); vi a(n - 100); iota(all(a), 0); vi b; set_difference(all(a), all(res), inserter(b, b.end())); dump(b); repe(x, b) { dump(bitset<16>(x)); } exit(0); } /* 1 11 29 55 89 115 165 239 305 379 429 519 617 707 853 991 1121 1259 1405 1495 1721 1811 1989 2191 2385 2587 2765 3047 3209 3491 3765 4031 4289 4555 4829 0000000000000001 0000000000001011 0000000000011101 0000000000110111 0000000001011001 0000000001110011 0000000010100101 0000000011101111 0000000100110001 0000000101111011 0000000110101101 0000001000000111 0000001001101001 0000001011000011 0000001101010101 0000001111011111 0000010001100001 0000010011101011 0000010101111101 0000010111010111 0000011010111001 0000011100010011 0000011111000101 0000100010001111 0000100101010001 0000101000011011 0000101011001101 0000101111100111 0000110010001001 0000110110100011 0000111010110101 0000111110111111 0001000011000001 0001000111001011 0001001011011101 */ void zikken2() { int n = 50; vi res; repi(k, 1, n) { auto x = integer_sqrt(k); dump(bitset<8>(x), bitset<8>(k)); } exit(0); } void Main() { ll n; cin >> n; dump(bitset<64>(n)); //if (n <= (ll)1e4) { // repi(k, 0, 2 * n) { // auto rk = integer_sqrt(k); // if ((rk ^ k) == n) { // cout << k << "\n"; // return; // } // } //} int b = (msb(n) + 2) / 2; dump("b:", b); ll k = (n >> b) << b; dump("k:", k, bitset<64>(k)); while (b >= 10) { ll kl = k; ll kr = k + (1LL << b) - 1; dump(kl, kr, bitset<64>(kl), bitset<64>(kr)); auto sl = integer_sqrt(kl); auto sr = integer_sqrt(kr); dump(sl, sr, bitset<64>(sl), bitset<64>(sr)); if (sl == sr) { repir(b2, b - 1, 0) { k ^= (getb(n, b2) ^ getb(sl, b2)) << b2; b = b2; } auto rk = integer_sqrt(k); if ((rk ^ k) == n) { cout << k << "\n"; return; } else { cout << -1 << "\n"; return; } } repir(b2, b - 1, 0) { if (getb(sl, b2) != getb(sr, b2)) break; k ^= (getb(n, b2) ^ getb(sl, b2)) << b2; b = b2; } dump("b:", b); dump("k:", k, bitset<64>(k)); } rep(hoge, 1024) { auto rk = integer_sqrt(k); if ((rk ^ k) == n) { cout << k << "\n"; return; } k++; } cout << -1 << "\n"; } int main() { // input_from_file("input.txt"); // output_to_file("output.txt"); int t = 1; cin >> t; // マルチテストケースの場合 while (t--) { dump("------------------------------"); Main(); } }