Good Bye 2014 E - New Year Domino 单调栈+倍增

E - New Year Domino

思路:我用倍增写哒,离线可以不用倍增。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg
using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 10000;

int n, a[N], b[N], c[N], stk[N], R[N], tot;
int nx[N][20], cost[N][20];

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d%d", &a[i], &b[i]);

    for(int i = 1; i <= n; i++)
        c[i] = a[i] + b[i];

    for(int i = n; i >= 1; i--) {
        while(tot && c[stk[tot]] < c[i]) tot--;
        if(!tot) R[i] = 0;
        else R[i] = stk[tot];
        stk[++tot] = i;
    }

    for(int i = 1; i <= n; i++) {
        nx[i][0] = R[i];
        cost[i][0] = max(0, a[R[i]] - a[i] - b[i]);
    }

    for(int j = 1; j < 20; j++) {
        for(int i = 1; i <= n; i++) {
            nx[i][j] = nx[nx[i][j - 1]][j - 1];
            cost[i][j] = cost[i][j - 1] + cost[nx[i][j - 1]][j - 1];
        }
    }

    int q; scanf("%d", &q);
    while(q--) {
        int l, r; scanf("%d%d", &l, &r);
        int ans = 0;
        for(int i = 19; i >= 0; i--) {
            if(!nx[l][i] || nx[l][i] >= r) continue;
            ans += cost[l][i];
            l = nx[l][i];
        }
        ans += max(0, a[r] - a[l] - b[l]);
        printf("%d\n", ans);
    }
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9631711.html