Reverse st (luoguP1198 [JSOI2008] Maximum

https://www.luogu.org/problem/P1198

The meaning of problems

Now request you to maintain a number of columns, it requires the following two actions:

1, the query operation.

grammar:Q L

Function: the maximum number of queries in the end of the number of columns in the current number L, and outputs the value of this number.

Restrictions: L does not exceed the length of the current sequence. (L> 0)

2, the insertion operation.

grammar:A n

Function: adding n t, where t is the last answer to a query operation (if not already performed a query operation, t = 0), and the result of a fixed constant modulo D, is inserted into the resulting answer the end of the sequence.

Restrictions: n is integer (possibly negative) and in the entire length range.

Note: The number of columns is initially empty, not a number.

analysis

Could have been done to find a topic tree line, but the question clearly overkill .... Why?

We note that when it is inserted into the end of this number only to the number of columns, but only when the query after query the L number.

So, we can use a reverse st tables to maintain (this is a solution to a problem after watching thought ... ashamed ...) (reverse st means that st [i] [j] is [i- ( 1 << j) +1, i] maximum)

First think how insert, that is what needs to change after insertion. Think "after the maximum number of queries L", come to this table right boundary st must be n (the number of numbers), so we think the reverse st table, because of this, the only thing we need to change the amount is st [n] [...], st n number of previous modifications do not, because we are reversed ah.

Think again how the query, as long as you put yourBrain Thinking upside down, reverse RMQ can achieve.

Thoughts after the reference

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
#define ll long long
#define MAX 200000+9

int n,m;
ll f[MAX][21], a[MAX], D;//f[i][j]表示[i-(1<<j)+1, i]的最大值

void putback(int x) {
    f[x][0] = a[x];// 别忘了放到最后 
    for(int i = 1; x-(1<<i)+1 >= 1; i++) {
        f[x][i] = max(f[x][i-1], f[x-(1<<(i-1))][i-1]);
    }
}

ll RMQ(int l, int r) {
    int k = 0;
    while((1<<(k+1) <= r-l+1)) k++;
    return max(f[r][k], f[l+(1<<k)-1][k]);//始终是反向思考
}

int main() {
    scanf("%d%lld",&m,&D);
    char cmd;
    ll x, t = 0;
    for(int i = 1; i <= m; i++) {
        cin>>cmd;
        if(cmd == 'A') {
            scanf("%lld",&x);
            a[++n] = (x+t)%D;
            putback(n);
        } else {
            int L;
            scanf("%d", &L);
            if(L == 1) {
                printf("%lld\n", a[n]);
                t = a[n];
                continue;
            }
            ll ans;
            ans = RMQ(n-L+1, n);
            printf("%lld\n", ans);
            t = ans;
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/tyner/p/11267630.html