#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<ll, ll> pii;
random_device rd;
mt19937 rng(0);
const int rdseed = (uint64_t)(make_unique<char>().get()) ^ chrono::high_resolution_clock::now().time_since_epoch().count();
const ll N = 1e18;
const ll NUM_ELEM = 2e5;
const ll NUM_QUERIES = 2e5;
uniform_int_distribution<ll> uni(1LL, N);
/***************************************************/
struct Node {
Node *lp, *rp;
ll sum;
};
inline ll eval(Node* p) {
return p ? p->sum : 0LL;
}
const ll bufSize = NUM_ELEM * (log2(N) + 1);
Node buf[bufSize];
Node *newNode() {
static auto ptr = buf;
return ptr++;
}
ll getSum(Node* cur, ll l, ll r, ll x, ll y) {
if (!cur || x > r || y < l) return 0;
if (x <= l && r <= y) {
return cur->sum;
}
ll m = (l + r) / 2;
return getSum(cur->lp, l, m, x, y) + getSum(cur->rp, m + 1, r, x, y);
}
void update(Node*& cur, ll l, ll r, ll pos, ll val) {
if (!cur) cur = newNode();
if (l == r) {
cur->sum = val;
} else {
ll m = (l + r) / 2;
if (pos <= m) {
update(cur->lp, l, m, pos, val);
} else {
update(cur->rp, m + 1, r, pos, val);
}
cur->sum = eval(cur->lp) + eval(cur->rp);
}
}
Node *root;
/***************************************************/
inline int hash_f(int x) { return ((x >> 16) ^ x) * 0x45d9f3b; }
struct chash {
int operator()(int x) const { return hash_f(x); }
};
gp_hash_table<ll, ll, chash> seg;
ll get(ll x) {
auto res = seg.find(x);
return (res == seg.end()) ? 0 : res->second;
// return (seg.find(x) == seg.end()) ? 0 : seg[x];
}
void modify(ll p, ll val) {
for (seg[p += N] = val; p > 0; p >>= 1) {
seg[p >> 1] = get(p) + get(p ^ 1);
}
}
ll query(ll l, ll r) {
ll res = 0;
for (l += N, r += N; l < r; l >>= 1, r >>= 1) {
if (l & 1)
res += get(l++);
if (r & 1)
res += get(--r);
}
return res;
}
/***************************************************/
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
vector<pii> elems;
for (ll i = 0; i < NUM_ELEM; i++) {
elems.push_back({uni(rng), uni(rng)});
}
vector<pii> queries;
for (ll i = 0; i < NUM_QUERIES; i++) {
ll a = uni(rng), b = uni(rng);
if (a > b)
swap(a, b);
queries.push_back({a, b});
}
vector<ll> ans1, ans2;
clock_t begin;
begin = clock();
for (auto i : elems) {
modify(i.first, i.second);
}
for (auto i : queries) {
ans2.push_back(query(i.first, i.second + 1));
}
cout << "policy hash: " << (double)(clock() - begin) / CLOCKS_PER_SEC << endl;
seg.clear();
begin = clock();
for (auto i : elems) {
update(root, 1, N, i.first, i.second);
}
for (auto i : queries) {
ans1.push_back(getSum(root, 1, N, i.first, i.second));
}
cout << "pointer: " << (double)(clock() - begin) / CLOCKS_PER_SEC << endl;
for (int i = 0; i < ans1.size(); i++) {
assert(ans1[i] == ans2[i]);
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwojaW5jbHVkZSA8ZXh0L3BiX2RzL2Fzc29jX2NvbnRhaW5lci5ocHA+CnVzaW5nIG5hbWVzcGFjZSBfX2dudV9wYmRzOwoKdHlwZWRlZiBsb25nIGxvbmcgbGw7CnR5cGVkZWYgcGFpcjxsbCwgbGw+IHBpaTsKcmFuZG9tX2RldmljZSByZDsKbXQxOTkzNyBybmcoMCk7CmNvbnN0IGludCByZHNlZWQgPSAodWludDY0X3QpKG1ha2VfdW5pcXVlPGNoYXI+KCkuZ2V0KCkpIF4gY2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpOwoKY29uc3QgbGwgTiA9IDFlMTg7CmNvbnN0IGxsIE5VTV9FTEVNID0gMmU1Owpjb25zdCBsbCBOVU1fUVVFUklFUyA9IDJlNTsKCnVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjxsbD4gdW5pKDFMTCwgTik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RydWN0IE5vZGUgewoJTm9kZSAqbHAsICpycDsKCWxsIHN1bTsKfTsKaW5saW5lIGxsIGV2YWwoTm9kZSogcCkgewoJcmV0dXJuIHAgPyBwLT5zdW0gOiAwTEw7Cn0KCmNvbnN0IGxsIGJ1ZlNpemUgPSBOVU1fRUxFTSAqIChsb2cyKE4pICsgMSk7Ck5vZGUgYnVmW2J1ZlNpemVdOwpOb2RlICpuZXdOb2RlKCkgeyAKCXN0YXRpYyBhdXRvIHB0ciA9IGJ1ZjsKCXJldHVybiBwdHIrKzsKfQoKbGwgZ2V0U3VtKE5vZGUqIGN1ciwgbGwgbCwgbGwgciwgbGwgeCwgbGwgeSkgewoJaWYgKCFjdXIgfHwgeCA+IHIgfHwgeSA8IGwpIHJldHVybiAwOwogICAgaWYgKHggPD0gbCAmJiByIDw9IHkpIHsKICAgICAgICByZXR1cm4gY3VyLT5zdW07CiAgICB9CiAgICBsbCBtID0gKGwgKyByKSAvIDI7CiAgICByZXR1cm4gZ2V0U3VtKGN1ci0+bHAsIGwsIG0sIHgsIHkpICsgZ2V0U3VtKGN1ci0+cnAsIG0gKyAxLCByLCB4LCB5KTsKfQp2b2lkIHVwZGF0ZShOb2RlKiYgY3VyLCBsbCBsLCBsbCByLCBsbCBwb3MsIGxsIHZhbCkgewoJaWYgKCFjdXIpIGN1ciA9IG5ld05vZGUoKTsKCWlmIChsID09IHIpIHsKCQljdXItPnN1bSA9IHZhbDsKCX0gZWxzZSB7CgkJbGwgbSA9IChsICsgcikgLyAyOwoJCWlmIChwb3MgPD0gbSkgewoJCQl1cGRhdGUoY3VyLT5scCwgbCwgbSwgcG9zLCB2YWwpOwoJCX0gZWxzZSB7CgkJCXVwZGF0ZShjdXItPnJwLCBtICsgMSwgciwgcG9zLCB2YWwpOwoJCX0KCQljdXItPnN1bSA9IGV2YWwoY3VyLT5scCkgKyBldmFsKGN1ci0+cnApOwoJfQp9Ck5vZGUgKnJvb3Q7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKaW5saW5lIGludCBoYXNoX2YoaW50IHgpIHsgcmV0dXJuICgoeCA+PiAxNikgXiB4KSAqIDB4NDVkOWYzYjsgfQoKc3RydWN0IGNoYXNoIHsKICAgIGludCBvcGVyYXRvcigpKGludCB4KSBjb25zdCB7IHJldHVybiBoYXNoX2YoeCk7IH0KfTsKCmdwX2hhc2hfdGFibGU8bGwsIGxsLCBjaGFzaD4gc2VnOwoKbGwgZ2V0KGxsIHgpIHsKICAgIGF1dG8gcmVzID0gc2VnLmZpbmQoeCk7CiAgICByZXR1cm4gKHJlcyA9PSBzZWcuZW5kKCkpID8gMCA6IHJlcy0+c2Vjb25kOwogICAgLy8gcmV0dXJuIChzZWcuZmluZCh4KSA9PSBzZWcuZW5kKCkpID8gMCA6IHNlZ1t4XTsKfQp2b2lkIG1vZGlmeShsbCBwLCBsbCB2YWwpIHsKICAgIGZvciAoc2VnW3AgKz0gTl0gPSB2YWw7IHAgPiAwOyBwID4+PSAxKSB7CiAgICAgICAgc2VnW3AgPj4gMV0gPSBnZXQocCkgKyBnZXQocCBeIDEpOwogICAgfQp9CgpsbCBxdWVyeShsbCBsLCBsbCByKSB7CiAgICBsbCByZXMgPSAwOwogICAgZm9yIChsICs9IE4sIHIgKz0gTjsgbCA8IHI7IGwgPj49IDEsIHIgPj49IDEpIHsKICAgICAgICBpZiAobCAmIDEpCiAgICAgICAgICAgIHJlcyArPSBnZXQobCsrKTsKICAgICAgICBpZiAociAmIDEpCiAgICAgICAgICAgIHJlcyArPSBnZXQoLS1yKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgppbnQgbWFpbigpIHsKICAgIGlvczo6c3luY193aXRoX3N0ZGlvKDApOwogICAgY2luLnRpZSgwKTsKICAgIHZlY3RvcjxwaWk+IGVsZW1zOwogICAgZm9yIChsbCBpID0gMDsgaSA8IE5VTV9FTEVNOyBpKyspIHsKICAgICAgICBlbGVtcy5wdXNoX2JhY2soe3VuaShybmcpLCB1bmkocm5nKX0pOwogICAgfQogICAgdmVjdG9yPHBpaT4gcXVlcmllczsKICAgIGZvciAobGwgaSA9IDA7IGkgPCBOVU1fUVVFUklFUzsgaSsrKSB7CiAgICAgICAgbGwgYSA9IHVuaShybmcpLCBiID0gdW5pKHJuZyk7CiAgICAgICAgaWYgKGEgPiBiKQogICAgICAgICAgICBzd2FwKGEsIGIpOwogICAgICAgIHF1ZXJpZXMucHVzaF9iYWNrKHthLCBifSk7CiAgICB9CiAgICB2ZWN0b3I8bGw+IGFuczEsIGFuczI7CiAgICBjbG9ja190IGJlZ2luOwogICAgYmVnaW4gPSBjbG9jaygpOwogICAgZm9yIChhdXRvIGkgOiBlbGVtcykgewogICAgICAgIG1vZGlmeShpLmZpcnN0LCBpLnNlY29uZCk7CiAgICB9CiAgICBmb3IgKGF1dG8gaSA6IHF1ZXJpZXMpIHsKICAgICAgICBhbnMyLnB1c2hfYmFjayhxdWVyeShpLmZpcnN0LCBpLnNlY29uZCArIDEpKTsKICAgIH0KICAgIGNvdXQgPDwgInBvbGljeSBoYXNoOiAiIDw8IChkb3VibGUpKGNsb2NrKCkgLSBiZWdpbikgLyBDTE9DS1NfUEVSX1NFQyA8PCBlbmRsOwogICAgc2VnLmNsZWFyKCk7CiAgICBiZWdpbiA9IGNsb2NrKCk7CiAgICBmb3IgKGF1dG8gaSA6IGVsZW1zKSB7CiAgICAgICAgdXBkYXRlKHJvb3QsIDEsIE4sIGkuZmlyc3QsIGkuc2Vjb25kKTsKICAgIH0KICAgIGZvciAoYXV0byBpIDogcXVlcmllcykgewogICAgICAgIGFuczEucHVzaF9iYWNrKGdldFN1bShyb290LCAxLCBOLCBpLmZpcnN0LCBpLnNlY29uZCkpOwogICAgfQogICAgY291dCA8PCAicG9pbnRlcjogIiA8PCAoZG91YmxlKShjbG9jaygpIC0gYmVnaW4pIC8gQ0xPQ0tTX1BFUl9TRUMgPDwgZW5kbDsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGFuczEuc2l6ZSgpOyBpKyspIHsKICAgICAgICBhc3NlcnQoYW5zMVtpXSA9PSBhbnMyW2ldKTsKICAgIH0KfQ==