题目
大意:维护一个数列,有两种操作:
- 查询操作Q L:查询当前数列中末尾L个数中的最大的数
- 插入操作A n:将n加上t再对D取模,将所得值插入数列末尾
解决方案
由题意知,只有两种操作:单点修改、区间查询
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const ll INF = (ll) << ;
const int maxn = + ;
ll maxv[maxn << ];
int n;
ll mod; int ql, qr; //查询[ql, qr]中的最小值
ll query(int o,int L,int R)
{
//printf("o:%d L:%d R:%d\n", o, L, R);
int M = L + (R - L) / ;
ll ans = -INF;
if(ql <= L && R <= qr) return maxv[o];
if(ql <= M) ans = max(ans, query(*o, L, M));
if(qr > M) ans = max(ans, query(*o+, M+, R));
return ans;
} ll P, v; //修改A[p]=v
void update(int o, int L, int R)
{
int M = L + (R-L)/;
if(L == R) maxv[o] = v; //更新叶子结点
else
{
if(P <= M) update(*o, L ,M);
else update(*o+, M+, R);
maxv[o] = max(maxv[*o], maxv[*o+]); //更新非叶子结点
}
} void print_debug(int o, int L, int R)
{
printf("o:%d L:%d R:%d maxv:%lld\n", o, L, R, maxv[o]);
if(R > L)
{
int M = L + (R - L) / ;
print_debug(*o, L, M);
print_debug(*o+, M+, R);
}
} int main()
{
scanf("%d%lld", &n, &mod);
char order[];
int cnt = ;
ll val, t = ; for(int i = ;i <= (n <<);i++) maxv[i] = -INF; //初始化 for(int i = ;i < n;i++)
{
scanf("%s", order);
if(order[] == 'A')
{
scanf("%lld", &val);
P = ++cnt;
v = (val + t + mod) % mod;
update(, , n);
//print_debug(1, 1, n);
}
else
{
int L;
//printf("cnt: %d\n", cnt);
scanf("%d", &L);
ql = cnt - L + ; qr = cnt;
t = query(, , n);
printf("%lld\n", t);
//print_debug(1, 1, n);
}
} return ;
}