如果还没看题目的可以先去看一下题目
前置知识线段树
这个题目就是两个操作,一个是添加数据,一个是查询区间最大值,但是由于数据范围达到1e5,所以我直接想到的就是线段树了,下面我们来看看线段树要怎么做。
首先是建树,由于题目中的数据有负数,负数,负数,所以大家建树的时候一定要注意!!!初始化权值和懒人标记为-(1<<62)。
然后是更新,这个就和普通的线段树更新一样,需要用到懒人标记的时候就向下更新懒人标记。
最后是查询,也和模板线段树一样,遇到要更新懒人标记的时候及时更新懒人标记就好了。
上代码!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
#define pi acos(-1)
#define pii pair<int, int>
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define piii pair<pii, int>
#define uf(a, b, i) for (register int i = (a); i <= (b); ++i)
#define df(a, b, i) for (register int i = (a); i >= (b); --i)
using namespace std;
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
template<class T>
inline void print(T x) {
if(x > 9) print(x/10);
putchar(x%10 + '0');
}
template<class T>
T Max(T a, T b) {
return a > b ? a : b;
}
template<class T>
T Min(T a, T b) {
return a < b ? a : b;
}
const ll mod = 1e9 + 7;
const ll inf = -4611686018427387904;//-(1<<62)
ll ans;
int p;
struct Tree {
int l, r;
ll val, lazy;
} tree[800005];
void build(int node, int l, int r) {
tree[node].val = inf; tree[node].lazy = inf;
tree[node].l = l; tree[node].r = r;
if (l == r) return ;
build(node<<1, l, l+r>>1);
build(node<<1|1, (l+r>>1)+1, r);
}
void down(int node) {
tree[node<<1].lazy = Max(tree[node<<1].lazy, tree[node].lazy);
tree[node<<1].val = Max(tree[node<<1].val, tree[node].lazy);
tree[node<<1|1].lazy = Max(tree[node<<1|1].lazy, tree[node].lazy);
tree[node<<1|1].val = Max(tree[node<<1|1].val, tree[node].lazy);
tree[node].lazy = inf;
}
void update(int node, int l, int r, ll val) {
if (1 <= tree[node].l && tree[node].r <= r) {
tree[node].val = Max(tree[node].val, val);
tree[node].lazy = Max(tree[node].lazy, val);
return ;
} else {
down(node);
if ((tree[node].l + tree[node].r >> 1) >= l) update(node<<1, l, r, val);
if ((tree[node].l + tree[node].r >> 1) < r) update(node<<1|1, l, r, val);
tree[node].val = Max(tree[node<<1].val, tree[node<<1|1].val);
}
}
void ask(int node, int l, int r) {
if (tree[node].l >= l && tree[node].r <= r) {
ans = Max(ans, tree[node].val);
return ;
} else {
down(node);
if ((tree[node].l + tree[node].r >> 1) >= l) ask(node<<1, l, r);
if ((tree[node].l + tree[node].r >> 1) < r) ask(node<<1|1, l, r);
}
}
int n, m, t, cnt;
int a[200005];
void scan() {
n = read(); p = read();
}
void work() {
build(1, 1, n);
uf (1, n, i) {
char c;
int val;
cin >> c >> val;
if (c == 'A') {
update(1, 1, ++cnt, (val+t)%p);
} else {
ans = inf;
ask(1, cnt-val+1, cnt);
cout << ans << endl;
t = ans;
}
}
}
int main() {
scan();
work();
return 0;
}
/*
5 100
A -10
Q 1
A 5
Q 1
Q 2
*/