用单调栈维护一下就好啦。。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 200005 #define maxm 2000005 #define eps 1e-10 #define mod 1000000007 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> //#pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head int sum[maxn << 2]; int add[maxn << 2]; vector<pair<int, int> > q[maxn]; pair<int, int> p; int res[maxn]; stack<int> s; int a[maxn]; int b[maxn]; int n, m; void pushup(int o) { sum[o] = sum[ls] + sum[rs]; } void pushdown(int o, int L, int R) { if(add[o]) { int mid = (L + R) >> 1; sum[ls] += (mid - L + 1) * add[o]; sum[rs] += (R - mid) * add[o]; add[ls] += add[o]; add[rs] += add[o]; add[o] = 0; } } void update(int o, int L, int R, int ql, int qr, int v) { if(ql <= L && qr >= R) { sum[o] += (R - L + 1) * v; add[o] += v; return; } pushdown(o, L, R); int mid = (L + R) >> 1; if(ql <= mid) update(lson, ql, qr, v); if(qr > mid) update(rson, ql, qr, v); pushup(o); } int query(int o, int L, int R, int pos) { if(L == R) return sum[o]; pushdown(o, L, R); int mid = (L + R) >> 1; int ans = 0; if(pos <= mid) ans = query(lson, pos); else ans = query(rson, pos); pushup(o); return ans; } void read(void) { int aa, bb; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%d", &a[i], &b[i]); scanf("%d", &m); for(int i = 1; i <= m; i++) { scanf("%d%d", &aa, &bb); q[bb].push_back(mp(aa, i)); } } void work(void) { for(int k = 2; k <= n; k++) { while(!s.empty()) { int id = s.top(); if(a[k-1] + b[k-1] >= a[id] + b[id]) s.pop(); else break; } s.push(k-1); while(!s.empty()) { int id = s.top(); if(a[id] + b[id] >= a[k]) break; int t = a[k] - a[id] - b[id], pre = 0; s.pop(); if(!s.empty()) pre = s.top(); update(1, 1, n, pre + 1, id, t); } for(int i = 0; i < q[k].size(); i++) res[q[k][i].second] = query(1, 1, n, q[k][i].first); } for(int i = 1; i <= m; i++) printf("%d\n", res[i]); } int main(void) { read(); work(); return 0; }