bzoj1016 SCOI2008 最大数Maxnumber

题意: 有一个序列,首先有两种操作:①查找后L个数中最大数;②[(最近一次查询得到的答案 + 常数R) % 常数D] 得到一个新数插入到序列的末尾,如果序列中没有数,那么用 0 代替 最近一次查询得到的答案。

题解:一个数插入到序列中,查询时她会影响到前面比它小的数;也就是说一个新数插入,那么这个数前面的比它小的数将没有贡献。所以想到单调队列作为此题的核心算法。

CODE:

 

/*
Author: JDD
PROG: bzoj1012 最大数
DATE: 2015.9.22 
*/

#include <cstdio> 
#define REP(i, s, n) for(int i = s; i <= n; i ++)
#define REP_(i, s, n) for(int i = n; i >= s; i --)
#define MAX_N 200005

using namespace std;

int M, D, N = 0, h = 1, t = 1;
int a[MAX_N], R[MAX_N];

int find(int x)
{
    int l = h, r = t, mid;
    while(l < r){
        mid = (l + r) >> 1;
        if(R[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return l;
}

void work()
{
    scanf("%d%d", &M, &D);
    int ans = 0;
    while(M --){
        char s[3]; int x;
        scanf("%s%d", s + 1, &x);
        if(s[1] == 'A'){
            a[++ N] = (x + ans) % D;
            while(h < t && a[R[t]] < a[N]) t --;
            R[++ t] = N;
        } else {
            ans = a[R[find(N - x + 1)]];
            //printf("%d\n", find(N - x + 1));
            printf("%d\n", ans);
        }
        /*REP(i, 1, t) printf("%d ", R[i]);
        printf("\n");*/
    }    
}

int main()
{
    work();
    return 0;
}

 

posted @ 2015-09-22 19:33  ALXPCUN  阅读(...)  评论(... 编辑 收藏