Submission #829441

# Submission time Handle Problem Language Result Execution time Memory
829441 2023-08-18T10:41:58 Z GrindMachine Floppy (RMI20_floppy) C++17
28 / 100
83 ms 25448 KB
// Om Namah Shivaya

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x, y) ((x + y - 1) / (y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl

#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep1(i, n) for(int i = 1; i <= n; ++i)
#define rev(i, s, e) for(int i = s; i >= e; --i)
#define trav(i, a) for(auto &i : a)

template<typename T>
void amin(T &a, T b) {
    a = min(a, b);
}

template<typename T>
void amax(T &a, T b) {
    a = max(a, b);
}

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif

/*

refs:
https://codeforces.com/blog/entry/112664 (cartesian trees => construction and properties)

*/

const int MOD = 1e9 + 7;
const int N = 4e4 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;

#include "floppy.h"

template<typename T>
struct sparse_table {
    /*============================*/

    T merge(T a, T b) {
        return max(a,b);
    }

    /*============================*/

    vector<vector<T>> table;
    vector<int> bin_log;
    int LOG = 0;

    sparse_table() {

    }

    sparse_table(vector<T> &a, int n) {
        while ((1 << LOG) <= n) LOG++;

        table = vector<vector<T>>(n, vector<T>(LOG));
        bin_log = vector<int>(n + 1);

        rep(i, n) table[i][0] = a[i];

        rep1(j, LOG - 1) {
            rep(i, n) {
                int jump = 1 << (j - 1);
                if (i + jump >= n) {
                    break;
                }

                table[i][j] = merge(table[i][j - 1], table[i + jump][j - 1]);
            }
        }

        bin_log[1] = 0;
        for (int i = 2; i <= n; ++i) {
            bin_log[i] = bin_log[i / 2] + 1;
        }
    }

    T query(int l, int r) {
        int len = r - l + 1;
        int k = bin_log[len];

        T val1 = table[l][k];
        T val2 = table[r - (1 << k) + 1][k];

        return merge(val1, val2);
    }
};

string bits = "";
sparse_table<pii> st;

void go1(int l, int r){
    if(l > r) return;
    if(l == r) return;

    auto [mx,pos] = st.query(l,r);

    string put = "";
    bool neq = false;

    rev(bit,15,0){
        int b1 = l&(1<<bit);
        int b2 = r&(1<<bit);
        if(b1 != b2) neq = true;

        if(neq){
            int b3 = 0;
            if(pos&(1<<bit)) b3 = 1;
            put.pb(char('0'+b3));
        }
    }

    bits += put;

    go1(l,pos-1);
    go1(pos+1,r);
}

void read_array(int subtask_id, const std::vector<int> &a) {
    int n = sz(a);
        
    vector<pii> b(n);
    rep(i,n) b[i] = {a[i],i};
    st = sparse_table<pii>(b,n);

    go1(0,n-1);

    save_to_floppy(bits);
}





vector<int> adj[N];

struct lca_algo {
    // LCA template (for graphs with 1-based indexing)

    int LOG = 1;
    vector<int> depth;
    vector<vector<int>> up;

    lca_algo() {

    }

    lca_algo(int n) {
        lca_init(n);
    }

    void lca_init(int n) {
        while ((1 << LOG) < n) LOG++;
        up = vector<vector<int>>(n + 1, vector<int>(LOG, n));
        depth = vector<int>(n + 1);

        lca_dfs(n, -1);
    }

    void lca_dfs(int node, int par) {
        trav(child, adj[node]) {
            if (child == par) conts;

            up[child][0] = node;
            rep1(j, LOG - 1) {
                up[child][j] = up[up[child][j - 1]][j - 1];
            }

            depth[child] = depth[node] + 1;

            lca_dfs(child, node);
        }
    }

    int lift(int u, int k) {
        rep(j, LOG) {
            if (k & (1 << j)) {
                u = up[u][j];
            }
        }

        return u;
    }

    int query(int u, int v) {
        if (depth[u] < depth[v]) swap(u, v);
        int k = depth[u] - depth[v];
        u = lift(u, k);

        if (u == v) return u;

        rev(j, LOG - 1, 0) {
            if (up[u][j] != up[v][j]) {
                u = up[u][j];
                v = up[v][j];
            }
        }

        u = up[u][0];
        return u;
    }

    int get_dis(int u, int v) {
        int lca = query(u, v);
        return depth[u] + depth[v] - 2 * depth[lca];
    }
};

string obits;
int ptr = 0;

void go2(int l, int r, int p){
    if(l > r) return;
    if(l == r){
        // cout << p+1 << " " << l+1 << endl;
        adj[p].pb(l);
        return;
    }

    int pos = 0;
    bool neq = false;

    rev(bit,15,0){
        int b1 = l&(1<<bit);
        int b2 = r&(1<<bit);
        if(b1 != b2) neq = true;

        if(neq){
            int bit = obits[ptr++]-'0';
            pos = pos*2 + bit;
        }
        else{
            pos = pos*2 + (b1 > 0);
        }
    }

    // cout << p+1 << " " << pos+1 << endl;
    adj[p].pb(pos);

    go2(l,pos-1,pos);
    go2(pos+1,r,pos);
}

std::vector<int> solve_queries(int subtask_id, int n,
        const std::string &bits,
        const std::vector<int> &L, const std::vector<int> &R) {

    obits = bits;
    go2(0,n-1,n);

    lca_algo LCA(n);

    int m = sz(L);
    vector<int> ans(m);
    
    rep(i,m){
        int l = L[i], r = R[i];
        ans[i] = LCA.query(l,r);
    }

    return ans;
}

Compilation message

stub.cpp: In function 'void run2()':
stub.cpp:101:30: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  101 |     if (query_answers.size() != M) {
      |         ~~~~~~~~~~~~~~~~~~~~~^~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 2596 KB Output is correct
2 Correct 2 ms 2612 KB Output is correct
3 Correct 3 ms 2776 KB Output is correct
4 Correct 2 ms 2732 KB Output is correct
5 Correct 2 ms 2600 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 22 ms 7732 KB Output is correct
2 Correct 24 ms 7592 KB Output is correct
3 Correct 33 ms 9616 KB Output is correct
4 Correct 24 ms 8612 KB Output is correct
5 Correct 25 ms 7632 KB Output is correct
# Verdict Execution time Memory Grader output
1 Partially correct 83 ms 25448 KB Partially correct
2 Partially correct 82 ms 25408 KB Partially correct
3 Incorrect 33 ms 19360 KB L is too large
4 Halted 0 ms 0 KB -