[51Nod1952] 栈

Description

不支持后端删除的dequeue,每次操作后查询最大值.

\(n\leq10^7\).时限1.5s,不用考虑读入/输出复杂度.

Solution

首先考虑如果没有后端删除怎么做, 直接开一个普通栈, 一个单调栈, 一边模拟一边算.

因为没有后端删除, 所以你维护一个单调队列就可以了.

需要用到一些实现上的细节技巧. 就是单调数据结构删除不是很好模拟.

考虑开一个普通栈/队列, 记录当前的操作编号, 然后如果你pop掉当前的操作, 看一下单调DS里是不是一样的就好了.

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
int read() {
    char ch = getchar();
    int x = 0, flag = 1;
    for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1;
    for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    return x * flag;
}
void write(int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x >= 10) write(x / 10);
    putchar(x % 10 + 48);
}

const int Maxn = 2e7 + 9, Mod = 1e9 + 7;
int n, A, B, C, x0, a, b, pmod, ls[Maxn];

void init() {
    n = read(); A = read(); B = read(); C = read(); ls[0] = read(); a = read(); b = read(); pmod = read();
}

int monoQue[Maxn], ml, mr, que[Maxn], head, lst;

void pushFront(int val) {
//  cout << "0 " << ls[val] << endl;
    if (mr - ml == 0) monoQue[++mr] = val;
    else if (ls[val] > ls[monoQue[mr]]) monoQue[++mr] = val;
    que[++lst] = val;
}

inline void pushBack(int val) {
//  cout << "1 " << ls[val] << endl;
    while (ml < mr && ls[monoQue[ml + 1]] < ls[val]) ++ml;
    monoQue[ml--] = val; que[head--] = val;
}

inline void pop() {
//  cout << "2 " << endl;
    if (monoQue[mr] == que[lst]) --mr;
    --lst;
}

inline LL getAns() { return ls[monoQue[mr]]; }

void solve() {
    ml = mr = head = lst = (int)1e7 + 4;
    LL ans = 0, cnt = 0;
    rep (i, 1, n) {
        ls[i] = (ls[i - 1] * 1ll * a % pmod + b) % pmod;
        if (ls[i] % (A + B + C) < A || cnt <= 1) pushFront(i), ++cnt;
        else if (ls[i] % (A + B + C) < A + B) pushBack(i), ++cnt;
        else if (ls[i] % (A + B + C) >= A + B) pop(), --cnt;
        (ans += getAns()) %= Mod;
    }
    cout << ans << endl;
}

int main() {
    freopen("51Nod1952.in", "r", stdin);
    freopen("51Nod1952.out", "w", stdout);

    init();
    solve();

#ifdef Qrsikno
    debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
    return 0;
}
posted @ 2019-03-07 19:13 Qrsikno 阅读(...) 评论(...) 编辑 收藏