NC20164_JSOI2007最大数
NC20164.JSOI_2007_最大数
思路
这个题目需要维护两个信息 数组长度 和 区间最大值
因为是在线查询,所以不好用\(ST\)表,所以考虑线段树
因为\(M\)最多\(200000\),所以最多\(200000\)个数,开一个\(800000\)的数组足够了
用一个变量去维护数组长度就好了
代码
神奇的代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
const int maxn = 2e5 + 5;
const int inf = 0x7f7f7f7f;
struct custom_hash
{
static uint64_t splitmix64(uint64_t x)
{
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
size_t operator () (uint64_t x) const
{
static const uint64_t FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count(); // 时间戳
return splitmix64(x + FIXED_RANDOM);
}
};
// 维护数组长度,区间最大值
int tree[4 * maxn];
int cur = 0;
int D = 0, M = 0, t = 0;
void update(int root)
{
int ch = root << 1;
tree[root] = std::max(tree[ch], tree[ch + 1]);
}
void modify(int root, int left, int right, int x, int pos)
{
if (left == right)
{
tree[root] = x;
return;
}
int ch = root << 1;
int mid = (left + right) >> 1;
if (pos <= mid)
{
modify(ch, left, mid, x, pos);
}
else
{
modify(ch + 1, mid + 1, right, x, pos);
}
update(root);
}
int query(int root, int left, int right, int x, int y)
{
if (x <= left && right <= y)
{
return tree[root];
}
int ch = root << 1;
int mid = (left + right) >> 1;
if (y <= mid)
{
return query(ch, left, mid, x, y);
}
else if(x > mid)
{
return query(ch + 1, mid + 1, right, x, y);
}
else
{
return std::max(query(ch, left, mid, x, mid), query(ch + 1, mid + 1, right, mid + 1, y));
}
}
void solve()
{
std::cin >> M >> D;
char f;
int tmp = 0;
while(M--)
{
std::cin >> f >> tmp;
if (f == 'Q')
{
int l = cur - tmp + 1;
t = query(1, 1, maxn, l, cur);
std::cout << t << endl;
}
else
{
cur++;
modify(1, 1, maxn, (tmp + t) % D, cur);
}
}
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr); std::cout.tie(nullptr);
//freopen("out.txt", "w", stdout);
int t = 1;
//std::cin >> t;
while(t--)
{
solve();
}
return 0;
}