题目
大意:维护一个数列,有两种操作:
- 查询操作Q L:查询当前数列中末尾L个数中的最大的数
- 插入操作A n:将n加上t再对D取模,将所得值插入数列末尾
解决方案
由题意知,只有两种操作:单点修改、区间查询
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 const ll INF = (ll)1 << 60; 6 const int maxn = 200000 + 10; 7 ll maxv[maxn << 2]; 8 int n; 9 ll mod; 10 11 int ql, qr; //查询[ql, qr]中的最小值 12 ll query(int o,int L,int R) 13 { 14 //printf("o:%d L:%d R:%d\n", o, L, R); 15 int M = L + (R - L) / 2; 16 ll ans = -INF; 17 if(ql <= L && R <= qr) return maxv[o]; 18 if(ql <= M) ans = max(ans, query(2*o, L, M)); 19 if(qr > M) ans = max(ans, query(2*o+1, M+1, R)); 20 return ans; 21 } 22 23 ll P, v; //修改A[p]=v 24 void update(int o, int L, int R) 25 { 26 int M = L + (R-L)/2; 27 if(L == R) maxv[o] = v; //更新叶子结点 28 else 29 { 30 if(P <= M) update(2*o, L ,M); 31 else update(2*o+1, M+1, R); 32 maxv[o] = max(maxv[2*o], maxv[2*o+1]); //更新非叶子结点 33 } 34 } 35 36 void print_debug(int o, int L, int R) 37 { 38 printf("o:%d L:%d R:%d maxv:%lld\n", o, L, R, maxv[o]); 39 if(R > L) 40 { 41 int M = L + (R - L) / 2; 42 print_debug(2*o, L, M); 43 print_debug(2*o+1, M+1, R); 44 } 45 } 46 47 int main() 48 { 49 scanf("%d%lld", &n, &mod); 50 char order[3]; 51 int cnt = 0; 52 ll val, t = 0; 53 54 for(int i = 1;i <= (n <<2);i++) maxv[i] = -INF; //初始化 55 56 for(int i = 0;i < n;i++) 57 { 58 scanf("%s", order); 59 if(order[0] == ‘A‘) 60 { 61 scanf("%lld", &val); 62 P = ++cnt; 63 v = (val + t + mod) % mod; 64 update(1, 1, n); 65 //print_debug(1, 1, n); 66 } 67 else 68 { 69 int L; 70 //printf("cnt: %d\n", cnt); 71 scanf("%d", &L); 72 ql = cnt - L + 1; qr = cnt; 73 t = query(1, 1, n); 74 printf("%lld\n", t); 75 //print_debug(1, 1, n); 76 } 77 } 78 79 return 0; 80 }
原文地址:https://www.cnblogs.com/lfri/p/11144813.html
时间: 2024-10-14 23:03:58