Submission #755179

#TimeUsernameProblemLanguageResultExecution timeMemory
755179StickfishBrperm (RMI20_brperm)C++17
13 / 100
3059 ms231860 KiB
#include "brperm.h" #include <map> #include <cassert> #include <iostream> #include <vector> using namespace std; using ll = long long; int rvs_pos(int i, int k) { int ans = 0; for (int bt = 0; bt < k; ++bt) if (i & (1 << bt)) { ans += 1 << (k - bt - 1); } return ans; } int n; string s; struct segment { int layer; int mod; int l; segment() {} segment(int layer_, int mod_, int l_): layer(layer_), mod(mod_), l(l_) {} int to_int() { return 8 * n * layer + ((n >> layer) + 4) * mod + l; //return blocks[layer][mod] + l; } int start_index() { return l * (1 << layer) + mod; } segment operator+(const int& x) const { return {layer, mod, l + x}; } segment sub_even() { if (l % 2) { return { layer + 1, mod + (1 << layer), l / 2 }; } else { return { layer + 1, mod, l / 2 }; } } segment sub_odd() { if (l % 2) { return { layer + 1, mod, l / 2 + 1 }; } else { return { layer + 1, mod + (1 << layer), l / 2 }; } } }; const ll MOD = 1000000007; const ll MAXN = 500008; ll pw(ll a, ll m) { if (!m) return 1; a %= MOD; if (m % 2) return a * pw(a, m - 1) % MOD; return pw(a * a, m / 2); } ll phash_[MAXN]; ll* phash = phash_ + 1; void init(int n0, const char s0[]) { n = n0; s = ""; for (int i = 0; i < n; ++i) s.push_back(s0[i]); //for (int bl = 0; (1 << bl) <= n; ++bl) { //for (int mod = 0; mod < (1 << bl); ++mod) { //blocks[bl].push_back(s.size()); //for (int i = mod; i < n; i += (1 << bl)) //s.push_back(s0[i]); //} //} ll mlt = 1; for (int i = 0; i < n; ++i) { phash[i] = (phash[i - 1] + (s[i] - 'a') * mlt) % MOD; mlt = (mlt * 30) % MOD; } } //map<ll, bool> mp[23]; //bool get_ans(segment a, segment b, int k) { //if (k < 6) { //int l0 = a.to_int(); //int l1 = b.to_int(); //for (int i = 0; i < (1 << k); ++i) //if (s[l0 + i] != s[l1 + rvs_pos(i, k)]) //return 0; //return 1; //} //ll hsh = 1ll * a.to_int() * n + b.to_int(); //if (mp[k].find(hsh) != mp[k].end()) //return mp[k][hsh]; //bool even = get_ans(a.sub_even(), b, k - 1); //bool odd = get_ans(a.sub_odd(), b + (1 << (k - 1)), k - 1); //return mp[k][hsh] = (even & odd); //} map<ll, ll> mp[23]; ll get_hash(segment a, int k) { int l = a.to_int(); if (k < 5) { int l0 = a.start_index(); ll hsh = 0; ll mlt = 1; for (int i = 0; i < (1 << k); ++i) { int j = rvs_pos(i, k) << a.layer; hsh = (hsh + mlt * (s[l0 + j] - 'a')) % MOD; mlt = mlt * 30 % MOD; } return hsh; } if (mp[k].find(l) != mp[k].end()) return mp[k][l]; ll even = get_hash(a.sub_even(), k - 1); ll odd = get_hash(a.sub_odd(), k - 1); return mp[k][l] = (even + odd * pw(30, (1 << (k - 1)))) % MOD; } int query(int l, int k) { if (k > 20 || l + (1 << k) > n) return 0; ll h1 = get_hash({0, 0, l}, k); ll h2 = (phash[l + (1 << k) - 1] - phash[l - 1] + MOD) * pw(30, MOD - 1 - l) % MOD; return h1 == h2; //return get_ans({0, 0, l}, {0, 0, l}, k); //for (int i = 0; i < (1 << k); ++i) { //if (s[l + i] != s[l + rvs_pos(i, k)]) { //return 0; //} //} //return 1; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...