SP7691 HOMO - Homo or Hetero
题意
动态维护一个序列,判断序列是否有两个以上不同的元素以及两个及以上相同的元素。
解法
这题 SPOJ 给出来源是 ACM ICPC 2009–2010, NEERC, Northern Subregional Contest,但是难度并不大,显然 STL 做这道题很容易,这里提供一个平衡树的做法。
显然,判断是否有两个及以上相同的元素,就是判断平衡树里面是否有一个结点的 cnt
是大于等于 bool
变量,表示以这个结点为根的子树里是否有两个及以上相同的元素,把这个信息每次都 pushup
,只需要判断根节点的这个变量的值即可。
判断是否有两个以上不同的元素,直接 set
即可。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <set>
#include <string>
#include <unordered_map>
using namespace std;
int n, cnt = 0;
set<int> st;
unordered_map<int, int> times;
const int N = 1e5 + 5, INF = INT_MAX;
class Treap
{
public:
int idx, root;
struct Node
{
int l, r, val, key;
int sz, cnt;
bool is_homogeneous;
//Node(int _l, int _r, int _val, int _key, int _sz, int _cnt, bool _p): l(_l), r(_r), val(_val), key(_key), sz(_sz), cnt(_cnt), is_homogeneous(_p){}
}tr[N];
int get_node(int key)
{
tr[++idx].key = key;
tr[idx].sz = tr[idx].cnt = 1;
tr[idx].val = rand();
tr[idx].is_homogeneous = false;
return idx;
}
void pushup(int u)
{
tr[u].sz = tr[tr[u].l].sz + tr[tr[u].r].sz + tr[u].cnt;
tr[u].is_homogeneous = tr[tr[u].l].is_homogeneous || tr[tr[u].r].is_homogeneous || tr[u].cnt >= 2;
}
void zig(int& x)
{
int q = tr[x].l;
tr[x].l = tr[q].r, tr[q].r = x, x = q;
pushup(tr[x].r), pushup(x);
}
void zag(int& x)
{
int q = tr[x].r;
tr[x].r = tr[q].l, tr[q].l = x, x = q;
pushup(tr[x].l), pushup(x);
}
void build()
{
get_node(INF), get_node(-INF);
root = 1, tr[1].r = 2;
if (tr[1].val < tr[2].val) zag(root);
}
void insert(int& x, int key)
{
if (!x) x = get_node(key);
else if (tr[x].key == key) tr[x].cnt++;
else if (tr[x].key > key)
{
insert(tr[x].l, key);
if (tr[tr[x].l].val > tr[x].val) zig(x);
}
else
{
insert(tr[x].r, key);
if (tr[tr[x].r].val > tr[x].val) zag(x);
}
pushup(x);
}
void del(int& x, int key)
{
if (!x) return;
if (tr[x].key == key)
{
if (tr[x].cnt > 1) tr[x].cnt--;
else if (tr[x].l || tr[x].r)
{
if (!tr[x].r || tr[tr[x].l].val > tr[tr[x].r].val)
{
zig(x);
del(tr[x].r, key);
}
else zag(x), del(tr[x].l, key);
}
else
{
tr[x].cnt--, tr[x].sz--, tr[x].is_homogeneous = false, x = 0;
}
}
else if (tr[x].key > key)
{
del(tr[x].l, key);
}
else del(tr[x].r, key);
pushup(x);
}
};
Treap tp;
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> n;
tp.build();
int cnt = 0;
while (n--)
{
string s;
cin >> s;
int k;
cin >> k;
if (s == "insert")
{
st.insert(k);
tp.insert(tp.root, k);
times[k]++;
cnt++;
}
else
{
if (st.size() && st.find(k) != st.end())
{
if (--times[k] == 0) st.erase(k);
cnt--;
tp.del(tp.root, k);
}
}
if (cnt == 0)
{
cout << "neither\n";
continue;
}
bool is_homogeneous = tp.tr[tp.root].is_homogeneous;
bool is_heterogeneous = st.size() > 1;
if (is_homogeneous && is_heterogeneous) cout << "both\n";
else if (is_homogeneous && !is_heterogeneous) cout << "homo\n";
else if (!is_homogeneous && is_heterogeneous) cout << "hetero\n";
else cout << "neither\n";
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现