Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define lsb(x) (x & (-x))
- #define ll long long
- #define ull unsigned long long
- // 220
- // 44
- using namespace std;
- const int MAXN = (int) 1e5;
- ll dst[2 * MAXN + 1], tot;
- int chain[2 * MAXN + 1], root[2 * MAXN + 1], ord[2 * MAXN + 1];
- int nodes, chains, n;
- struct Data {
- int nod;
- bool operator <(const Data &other) const {
- if(dst[nod] == dst[other.nod])
- return ord[nod] > ord[other.nod];
- return dst[nod] > dst[other.nod];
- }
- };
- multiset <Data> mst[MAXN + 1];
- int aint[4 * MAXN + 1];
- void build(int nod, int left, int right) {
- if(left == right) {
- mst[left].insert({left});
- aint[nod] = left;
- }
- else {
- int mid = (left + right) / 2;
- build(2 * nod, left, mid);
- build(2 * nod + 1, mid + 1, right);
- if(dst[aint[2 * nod]] <= dst[aint[2 * nod + 1]])
- aint[nod] = aint[2 * nod + 1];
- else
- aint[nod] = aint[2 * nod];
- }
- }
- void insert(int nod, int left, int right) {
- if(left == right) {
- mst[left].insert({nodes});
- if(dst[aint[nod]] <= dst[nodes])
- aint[nod] = nodes;
- }
- else {
- int mid = (left + right) / 2;
- if(root[nodes] <= mid)
- insert(2 * nod, left, mid);
- else
- insert(2 * nod + 1, mid + 1, right);
- int a = aint[2 * nod], b = aint[2 * nod + 1];
- if(dst[a] > dst[b] || (dst[a] == dst[b] && ord[a] > ord[b])) {
- aint[nod] = a;
- }
- else {
- aint[nod] = b;
- }
- }
- }
- void erase(int nod, int left, int right, int id) {
- if(left == right) {
- mst[left].erase(mst[left].find({id}));
- aint[nod] = mst[left].begin() -> nod;
- }
- else {
- int mid = (left + right) / 2;
- if(root[id] <= mid)
- erase(2 * nod, left, mid, id);
- else
- erase(2 * nod + 1, mid + 1, right, id);
- int a = aint[2 * nod], b = aint[2 * nod + 1];
- if(dst[a] > dst[b] || (dst[a] == dst[b] && ord[a] > ord[b])) {
- aint[nod] = a;
- }
- else {
- aint[nod] = b;
- }
- }
- }
- int query(int nod, int left, int right, int l, int r) {
- if(l > r)
- return 0;
- if(l <= left && right <= r) {
- return aint[nod];
- }
- else {
- int mid = (left + right) / 2;
- int a = 0, b = 0;
- if(l <= mid)
- a = query(2 * nod, left, mid, l, r);
- if(mid < r)
- b = query(2 * nod + 1, mid + 1, right, l, r);
- if(dst[a] < dst[b])
- return b;
- return a;
- }
- }
- inline void add(int y, int w, int t) {
- nodes++;
- if(y <= n) {
- chain[nodes] = ++chains;
- }
- else {
- chain[nodes] = chain[y];
- }
- root[nodes] = root[y];
- dst[nodes] = dst[y] + w;
- ord[nodes] = t;
- insert(1, 1, n);
- }
- inline void del(int y) {
- erase(1, 1, n, y);
- }
- inline int get_farthest(int x) {
- int pos = root[x];
- int nod2 = query(1, 1, n, pos + 1, n), nod1 = query(1, 1, n, 1, pos - 1);
- ll dst2 = dst[nod2] - dst[x];
- ll dst1 = tot + (dst[nod1] - dst[x]);
- if(nod1 == 0)
- dst1 = 0;
- if(nod2 == 0)
- dst2 = 0;
- if(dst1 > dst2)
- return nod1;
- return nod2;
- }
- int main() {
- //ifstream cin("A.in");
- //ofstream cout("A.out");
- int i, w, m;
- ios::sync_with_stdio(false);
- cin >> n;
- for(i = 2; i <= n + 1; i++) {
- cin >> w;
- dst[i] = dst[i - 1] + w;
- tot += w;
- }
- for(i = 1; i <= n; i++) {
- chain[i] = i;
- root[i] = i;
- ord[i] = i;
- }
- build(1, 1, n);
- cin >> m;
- nodes = chains = n;
- for(int t = n + 1; t <= m + n; t++) {
- int type, x;
- cin >> type >> x;
- if(type == 1) {
- cin >> w;
- int y = get_farthest(x);
- add(y, w, t);
- }
- if(type == 2) {
- cin >> w;
- add(x, w, t);
- }
- if(type == 3) {
- int y = get_farthest(x);
- del(y);
- }
- if(type == 4) {
- int y = get_farthest(x);
- ll ans;
- if(root[y] >= x) {
- ans = dst[y] - dst[x];
- }
- else {
- ans = dst[y] - dst[x] + tot;
- }
- cout << ans << "\n";
- }
- }
- //cin.close();
- //cout.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement