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; }