1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| const int N = 2e5 + 10;
int x[N],n,q;
struct node { int l,r; ll sum,tag,maxx; }tree[N<<2];
void pushup(int p) { tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum; tree[p].maxx = max(tree[p << 1].maxx,tree[p << 1 | 1].maxx); }
void build(int p,int l,int r) { tree[p].l = l,tree[p].r = r; if (l == r) { tree[p].maxx = tree[p].sum = x[l] - l; return ; } int mid = (l + r) >> 1; build(p << 1,l,mid); build(p << 1 | 1,mid + 1,r); pushup(p); }
void pushdown(int p) { if (!tree[p].tag) return ; tree[p << 1].tag = tree[p].tag; tree[p << 1].sum = (ll)tree[p].tag * (tree[p << 1].r - tree[p << 1].l + 1); tree[p << 1].maxx = tree[p].tag; tree[p << 1 | 1].tag = tree[p].tag; tree[p << 1 | 1].sum = (ll)tree[p].tag * (tree[p << 1 | 1].r - tree[p << 1 | 1].l + 1); tree[p << 1 | 1].maxx = tree[p].tag; tree[p].tag = 0; }
void change(int p,int x,int y,ll k) { if (tree[p].l >= x && tree[p].r <= y) { tree[p].sum = (ll)(tree[p].r - tree[p].l + 1) * k; tree[p].tag = k; tree[p].maxx = k; return ; } pushdown(p); int mid = (tree[p].l + tree[p].r) >> 1; if (x <= mid) change(p << 1,x,y,k); if (y > mid) change(p << 1 | 1,x,y,k); pushup(p); }
ll query(int p,int x,int y) { if (tree[p].l >= x && tree[p].r <= y) { return tree[p].sum; } pushdown(p); int mid = (tree[p].l + tree[p].r) >> 1; ll ans = 0; if (x <= mid) ans += query(p << 1,x,y); if (y > mid) ans += query(p << 1 | 1,x,y); return ans; }
int getpos(int p,int x,int y,int k) { if (tree[p].l == tree[p].r) { return tree[p].maxx < k ? tree[p].l + 1 : tree[p].l; } pushdown(p); int ans = 0; if (tree[p << 1].maxx >= k) ans = getpos(p << 1,x,y,k); else ans = getpos(p << 1 | 1,x,y,k); pushup(p); return ans; }
signed main() { read(n); for (int i = 1;i <= n;++i) read(x[i]); build(1,1,n); read(q); ll ans = 0; while (q--) { ll x,k;read(x,k);k -= x; int pos = getpos(1,1,n,k); if (pos > x) { --pos; ans += (ll)(pos - x + 1) * k - query(1,x,pos); change(1,x,pos,k); } else { ans += (ll)query(1,pos,x) - k * (x - pos + 1); change(1,pos,x,k); } } printf("%lld\n",ans); return 0; }
|