답안 #755179

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
755179 2023-06-09T13:44:59 Z Stickfish Brperm (RMI20_brperm) C++17
13 / 100
3000 ms 231860 KB
#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;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 2 ms 336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 2 ms 336 KB Output is correct
3 Execution timed out 3047 ms 144740 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 3059 ms 231860 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 2 ms 336 KB Output is correct
3 Execution timed out 3047 ms 144740 KB Time limit exceeded
4 Halted 0 ms 0 KB -