#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef long long ll;
random_device rd;
mt19937 rng(0);
uniform_int_distribution<ll> uni(1, 1e9);
typedef pair<ll, ll> pii;
const int rdseed = (uint64_t)(make_unique<char>().get()) ^ chrono::high_resolution_clock::now().time_since_epoch().count();
int hash_f(int x) { return ((x >> 16) ^ x) * 0x45d9f3b; }
struct chash {
int operator()(int x) const { return hash_f(x); }
};
struct node;
node *newNode();
struct node {
ll lv, rv, sum;
node *left, *right;
node() : left(NULL), right(NULL), sum(0) {}
inline void init(ll l, ll r) {
lv = l;
rv = r;
}
inline void extend() {
if (!left) {
ll m = (lv + rv) / 2;
left = newNode();
right = newNode();
left->init(lv, m);
right->init(m + 1, rv);
}
}
ll getSum(ll l, ll r) {
if (r < lv || rv < l) {
return 0;
}
if (l <= lv && rv <= r) {
return sum;
}
extend();
return left->getSum(l, r) + right->getSum(l, r);
}
void update(ll p, ll newVal) {
if (lv == rv) {
sum = newVal;
return;
}
extend();
(p <= left->rv ? left : right)->update(p, newVal);
sum = left->sum + right->sum;
}
};
ll bufSize = 5e7;
node buf[(int)5e7];
node *newNode() { return &buf[--bufSize]; }
ll N = 1e9;
ll NUM_ELEM = 2e5;
ll NUM_QUERIES = 2e5;
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();
node *rmq = newNode();
rmq->init(0, 1e9);
begin = clock();
for (auto i : elems) {
rmq->update(i.first, i.second);
}
for (auto i : queries) {
ans1.push_back(rmq->getSum(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+CnVzaW5nIG5hbWVzcGFjZSBfX2dudV9wYmRzOwoKdHlwZWRlZiBsb25nIGxvbmcgbGw7CnJhbmRvbV9kZXZpY2UgcmQ7Cm10MTk5Mzcgcm5nKDApOwp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248bGw+IHVuaSgxLCAxZTkpOwp0eXBlZGVmIHBhaXI8bGwsIGxsPiBwaWk7Cgpjb25zdCBpbnQgcmRzZWVkID0gKHVpbnQ2NF90KShtYWtlX3VuaXF1ZTxjaGFyPigpLmdldCgpKSBeIGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKTsKCmludCBoYXNoX2YoaW50IHgpIHsgcmV0dXJuICgoeCA+PiAxNikgXiB4KSAqIDB4NDVkOWYzYjsgfQoKc3RydWN0IGNoYXNoIHsKICAgIGludCBvcGVyYXRvcigpKGludCB4KSBjb25zdCB7IHJldHVybiBoYXNoX2YoeCk7IH0KfTsKCnN0cnVjdCBub2RlOwpub2RlICpuZXdOb2RlKCk7CgpzdHJ1Y3Qgbm9kZSB7CiAgICBsbCBsdiwgcnYsIHN1bTsKICAgIG5vZGUgKmxlZnQsICpyaWdodDsKCiAgICBub2RlKCkgOiBsZWZ0KE5VTEwpLCByaWdodChOVUxMKSwgc3VtKDApIHt9CgogICAgaW5saW5lIHZvaWQgaW5pdChsbCBsLCBsbCByKSB7CiAgICAgICAgbHYgPSBsOwogICAgICAgIHJ2ID0gcjsKICAgIH0KCiAgICBpbmxpbmUgdm9pZCBleHRlbmQoKSB7CiAgICAgICAgaWYgKCFsZWZ0KSB7CiAgICAgICAgICAgIGxsIG0gPSAobHYgKyBydikgLyAyOwogICAgICAgICAgICBsZWZ0ID0gbmV3Tm9kZSgpOwogICAgICAgICAgICByaWdodCA9IG5ld05vZGUoKTsKICAgICAgICAgICAgbGVmdC0+aW5pdChsdiwgbSk7CiAgICAgICAgICAgIHJpZ2h0LT5pbml0KG0gKyAxLCBydik7CiAgICAgICAgfQogICAgfQoKICAgIGxsIGdldFN1bShsbCBsLCBsbCByKSB7CiAgICAgICAgaWYgKHIgPCBsdiB8fCBydiA8IGwpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAobCA8PSBsdiAmJiBydiA8PSByKSB7CiAgICAgICAgICAgIHJldHVybiBzdW07CiAgICAgICAgfQoKICAgICAgICBleHRlbmQoKTsKICAgICAgICByZXR1cm4gbGVmdC0+Z2V0U3VtKGwsIHIpICsgcmlnaHQtPmdldFN1bShsLCByKTsKICAgIH0KCiAgICB2b2lkIHVwZGF0ZShsbCBwLCBsbCBuZXdWYWwpIHsKICAgICAgICBpZiAobHYgPT0gcnYpIHsKICAgICAgICAgICAgc3VtID0gbmV3VmFsOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBleHRlbmQoKTsKICAgICAgICAocCA8PSBsZWZ0LT5ydiA/IGxlZnQgOiByaWdodCktPnVwZGF0ZShwLCBuZXdWYWwpOwogICAgICAgIHN1bSA9IGxlZnQtPnN1bSArIHJpZ2h0LT5zdW07CiAgICB9Cn07CgpsbCBidWZTaXplID0gNWU3Owpub2RlIGJ1ZlsoaW50KTVlN107Cm5vZGUgKm5ld05vZGUoKSB7IHJldHVybiAmYnVmWy0tYnVmU2l6ZV07IH0KCmxsIE4gPSAxZTk7CmxsIE5VTV9FTEVNID0gMmU1OwpsbCBOVU1fUVVFUklFUyA9IDJlNTsKCmdwX2hhc2hfdGFibGU8bGwsIGxsLCBjaGFzaD4gc2VnOwoKbGwgZ2V0KGxsIHgpIHsKICAgIGF1dG8gcmVzID0gc2VnLmZpbmQoeCk7CiAgICByZXR1cm4gKHJlcyA9PSBzZWcuZW5kKCkpID8gMCA6IHJlcy0+c2Vjb25kOwogICAgLy8gcmV0dXJuIChzZWcuZmluZCh4KSA9PSBzZWcuZW5kKCkpID8gMCA6IHNlZ1t4XTsKfQp2b2lkIG1vZGlmeShsbCBwLCBsbCB2YWwpIHsKICAgIGZvciAoc2VnW3AgKz0gTl0gPSB2YWw7IHAgPiAwOyBwID4+PSAxKSB7CiAgICAgICAgc2VnW3AgPj4gMV0gPSBnZXQocCkgKyBnZXQocCBeIDEpOwogICAgfQp9CgpsbCBxdWVyeShsbCBsLCBsbCByKSB7CiAgICBsbCByZXMgPSAwOwogICAgZm9yIChsICs9IE4sIHIgKz0gTjsgbCA8IHI7IGwgPj49IDEsIHIgPj49IDEpIHsKICAgICAgICBpZiAobCAmIDEpCiAgICAgICAgICAgIHJlcyArPSBnZXQobCsrKTsKICAgICAgICBpZiAociAmIDEpCiAgICAgICAgICAgIHJlcyArPSBnZXQoLS1yKTsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCmludCBtYWluKCkgewogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oMCk7CiAgICBjaW4udGllKDApOwogICAgdmVjdG9yPHBpaT4gZWxlbXM7CiAgICBmb3IgKGxsIGkgPSAwOyBpIDwgTlVNX0VMRU07IGkrKykgewogICAgICAgIGVsZW1zLnB1c2hfYmFjayh7dW5pKHJuZyksIHVuaShybmcpfSk7CiAgICB9CiAgICB2ZWN0b3I8cGlpPiBxdWVyaWVzOwogICAgZm9yIChsbCBpID0gMDsgaSA8IE5VTV9RVUVSSUVTOyBpKyspIHsKICAgICAgICBsbCBhID0gdW5pKHJuZyksIGIgPSB1bmkocm5nKTsKICAgICAgICBpZiAoYSA+IGIpCiAgICAgICAgICAgIHN3YXAoYSwgYik7CiAgICAgICAgcXVlcmllcy5wdXNoX2JhY2soe2EsIGJ9KTsKICAgIH0KICAgIHZlY3RvcjxsbD4gYW5zMSwgYW5zMjsKICAgIGNsb2NrX3QgYmVnaW47CiAgICBiZWdpbiA9IGNsb2NrKCk7CiAgICBmb3IgKGF1dG8gaSA6IGVsZW1zKSB7CiAgICAgICAgbW9kaWZ5KGkuZmlyc3QsIGkuc2Vjb25kKTsKICAgIH0KICAgIGZvciAoYXV0byBpIDogcXVlcmllcykgewogICAgICAgIGFuczIucHVzaF9iYWNrKHF1ZXJ5KGkuZmlyc3QsIGkuc2Vjb25kICsgMSkpOwogICAgfQogICAgY291dCA8PCAicG9saWN5IGhhc2g6ICIgPDwgKGRvdWJsZSkoY2xvY2soKSAtIGJlZ2luKSAvIENMT0NLU19QRVJfU0VDIDw8IGVuZGw7CiAgICBzZWcuY2xlYXIoKTsKICAgIG5vZGUgKnJtcSA9IG5ld05vZGUoKTsKICAgIHJtcS0+aW5pdCgwLCAxZTkpOwogICAgYmVnaW4gPSBjbG9jaygpOwogICAgZm9yIChhdXRvIGkgOiBlbGVtcykgewogICAgICAgIHJtcS0+dXBkYXRlKGkuZmlyc3QsIGkuc2Vjb25kKTsKICAgIH0KICAgIGZvciAoYXV0byBpIDogcXVlcmllcykgewogICAgICAgIGFuczEucHVzaF9iYWNrKHJtcS0+Z2V0U3VtKGkuZmlyc3QsIGkuc2Vjb25kKSk7CiAgICB9CiAgICBjb3V0IDw8ICJwb2ludGVyOiAiIDw8IChkb3VibGUpKGNsb2NrKCkgLSBiZWdpbikgLyBDTE9DS1NfUEVSX1NFQyA8PCBlbmRsOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYW5zMS5zaXplKCk7IGkrKykgewogICAgICAgIGFzc2VydChhbnMxW2ldID09IGFuczJbaV0pOwogICAgfQp9