// 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 |
- |