luogu P1198 最大数

传送门

起手线段树肯定可以做

但是更优的做法也有 更好的利用了题面的性质

就是单调栈

单调栈功能没有单调队列那么强大 但是非常适合这道题

修改的时候按照单调栈的原则插入

查询的时候暴力二分

由于栈里是递减的 所以找一个最左边的满足要求的就行

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #include<vector>
 7 #include<iostream>
 8 #include<iomanip>
 9 #define itn int
10 #define ms(a,b) memset(a,b,sizeof a)
11 #define rep(i,a,n) for(int i = a;i <= n;i++)
12 #define per(i,n,a) for(int i = n;i >= a;i--)
13 #define inf 2147483647
14 using namespace std;
15 typedef long long ll;
16 ll read() {
17     ll as = 0,fu = 1;
18     char c = getchar();
19     while(c < '0' || c > '9') {
20         if(c == '-') fu = -1;
21         c = getchar();
22     }
23     while(c >= '0' && c <= '9') {
24         as = as * 10 + c - '0';
25         c = getchar();
26     }
27     return as * fu;
28 }
29 //head
30 const int N = 100006;
31 int T,n;
32 ll mod,ans;
33 struct node {
34     int idx;
35     ll x;
36 }stk[N];
37 
38 int top;
39 char cmd[5];
40 
41 void insert(ll x) {
42     while(top && stk[top].x < x) top--;
43     stk[++top].x = x,stk[top].idx = ++n;
44 }
45 
46 void query(int L) {
47     int l = 1,r = top;
48     while(l < r) {
49         int m = l+r >> 1;
50         if(stk[m].idx < n-L+1) l = m+1;
51         else r = m;
52     }
53     printf("%lld\n",ans = stk[r].x);
54 }
55 
56 int main() {
57     T = read(),mod = read();
58     while(T--) {
59         scanf("%s",cmd);
60         if(cmd[0] == 'Q') query(read());
61         if(cmd[0] == 'A') insert((read()+ans)%mod);
62     }
63 }
View Code

 

posted @ 2018-11-08 19:32  白怀潇  阅读(130)  评论(0编辑  收藏  举报