luogu P1198 最大数
起手线段树肯定可以做
但是更优的做法也有 更好的利用了题面的性质
就是单调栈
单调栈功能没有单调队列那么强大 但是非常适合这道题
修改的时候按照单调栈的原则插入
查询的时候暴力二分
由于栈里是递减的 所以找一个最左边的满足要求的就行
Code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
> 别忘了 总有人在等着你