题解 P6105 [Ynoi2010] y-fast trie
题意
给定常数
数据范围:
题解
以下默认
首先发现加入一个数的时先对它取模不影响正确性,也便于处理。
然后思考下这个模
发现可以分类讨论:
- 当
时,从集合中取最大值和次大值出来即可。 - 当
时,可以想到个暴力,对于每个 ,找到 ,在这些值中取最大值即可。
第一类情况 simple,我们只看第二类。
在这个过程中有许多的匹配是不优的,但我们都考虑了进去,每次插入删除要更新的个数级别是
有个结论,若
这个结论证明也很显然,存在这种情况说明
于是每次插入
因为插入集合后对 multiset
就好,注意找匹配时可能会找回自己,要判掉。
#include <bits/stdc++.h>
#define IT multiset<int>::iterator
using namespace std;
multiset<int> s, pr;
int n, c;
int mat(int x, bool t) {
if(!~x) return -1;
IT it = s.upper_bound(c - 1 - x);
if(it == s.begin()) return -1;
--it;
if(t && *it == x && s.count(x) == 1)
return it == s.begin() ? -1 : *--it;
return *it;
}
void ins(int x) {
if(s.empty()) { s.insert(x); return; }
int y = mat(x, 0), z = mat(y, 1), w = mat(z, 1);
if(~y && x > z) {
if(~z && y == w) pr.erase(pr.find(y + z));
pr.insert(x + y);
}
s.insert(x);
}
void del(int x) {
s.erase(s.find(x));
if(s.empty()) return;
int y = mat(x, 0), z = mat(y, 1), w = mat(z, 1);
if(~y && x > z) {
if(~z && y == w) pr.insert(y + z);
pr.erase(pr.find(x + y));
}
}
int qry() {
int res;
IT it = --s.end();
if(s.count(*it) >= 2) res = *it * 2 % c;
else res = (*it + *--it) % c;
if(!pr.empty()) res = max(*--pr.end(), res);
return res;
}
int main() {
scanf("%d%d", &n, &c);
int opt, x, last = 0;
while(n--) {
scanf("%d%d", &opt, &x);
x = (x ^ last) % c;
if(opt == 1) ins(x);
else del(x);
if(s.size() < 2) puts("EE"), last = 0;
else printf("%d\n", last = qry());
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话