• [51Nod1952] 栈


    Description

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

    (nleq10^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("
    Running time: %.3lf(s)
    ", clock() * 1.0 / CLOCKS_PER_SEC);
    #endif
        return 0;
    }
    
  • 相关阅读:
    网络初级篇之STP(BPDU详解与STP故障恢复)
    网络初级篇之STP(实验验证)
    3-1 查看帮助,命令历史与快捷键
    2-1 bash基本特性
    2-0 虚拟机与Linux系统安装
    0.操作系统的获取与安装
    1.计算机基础
    Linux下打包、压缩和解压
    JAVA基本数据类型转换的注意事项
    EditPlus代码自动完成的设置
  • 原文地址:https://www.cnblogs.com/qrsikno/p/10491661.html
Copyright © 2020-2023  润新知