Splay树求第k大模板
今天上午借着休息日得机会手撸了一下模板,终于对着模板调出来了。prev和next占用了std namespace里面的东西,然后报警我上次给关了所以。。。。。就花了3个小时吧。
inline加不加无所谓,但是代码规范一定要有。
#include <bits/stdc++.h> using namespace std; #define limit (1000000 + 5)//防止溢出 #define INF 0x3f3f3f3f #define inf 0x3f3f3f3f3f #define lowbit(i) i&(-i)//一步两步 #define EPS 1e-6 #define FASTIO ios::sync_with_stdio(false);cin.tie(0); #define ff(a) printf("%d\n",a ); #define pi(a,b) pair<a,b> #define rep(i, a, b) for(ll i = a; i <= b ; ++i) #define per(i, a, b) for(ll i = b ; i >= a ; --i) #define MOD 998244353 #define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next) #define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\data.txt", "rt", stdin) #define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\dabiao.txt", "wt", stdout) #define debug(x) cout<<x<<endl typedef long long ll; typedef unsigned long long ull; inline ll read(){ ll sign = 1, x = 0;char s = getchar(); while(s > '9' || s < '0' ){if(s == '-')sign = -1;s = getchar();} while(s >= '0' && s <= '9'){x = (x << 3) + (x << 1) + s - '0';s = getchar();} return x * sign; }//快读 void write(ll x){ if(x < 0) putchar('-'),x = -x; if(x / 10) write(x / 10); putchar(x % 10 + '0'); } struct node{ node *son[2], *fa;//确定三个最重要的 int key,cnt,size; node():fa(nullptr),key(0),cnt(0),size(0){ son[0] = son[1] = nullptr; } bool get(){ return fa->son[1] == this; } void update(){ size = son[1]->size + son[0]->size + cnt; } void clear(){ key = cnt = size = 0; } }tree[limit],*root,*null; int n,tot; node* make_tree_node(){ ++tot; tree[tot].son[0] = tree[tot].son[1] = tree[tot].fa = null; return &tree[tot]; } inline void rotate(node *cur){ node *fa = cur->fa,*grandfather = fa->fa; int rt = cur->get(), rt2 = fa->get(); fa->son[rt] = cur->son[rt ^ 1]; fa->son[rt]->fa = fa; cur->son[rt ^ 1] = fa; fa->fa = cur; cur->fa = grandfather; if(grandfather != null) grandfather->son[rt2] = cur; fa->update(); cur->update(); } inline void splay(node *cur){ for(node *fa = null ;(fa=cur->fa) != null;rotate(cur)) { if (fa->fa != null) { rotate((fa->get() == cur->get()) ? fa : cur); } } root = cur; } inline void insert(int x){ if(root == null){ root = make_tree_node(); root->key = x; root->cnt = root->size = 1; return; } for(node *cur = root,*fa = null; ; ){ if(x == cur->key){ cur->cnt++; splay(cur); return; } fa = cur; cur = cur->son[x > cur->key]; if(cur == null){ fa->son[x > fa->key]= cur = make_tree_node(); cur->key = x; cur->cnt=1; cur->fa=fa; splay(cur); return; } } } int kth(int k){ //求解k大 for(node * cur = root;;){ if(cur->son[0] != null && k <= cur->son[0]->size){ cur = cur->son[0]; }else{ int left_size = cur->son[0]->size + cur->cnt; if(k <= left_size)return cur->key; k -= left_size; cur = cur->son[1]; } } } int rank(int x){ int ans = 0; for(node * cur = root; ; ){ if(cur->son[0] != null && x < cur->key)cur = cur->son[0]; else{ ans += cur->son[0]->size; if(cur->key == x){ splay(cur); return ans; } ans += cur->cnt; cur = cur->son[1]; } } } node * pre(){//前驱 node * cur = root->son[0]; for(;cur->son[1] != null;cur = cur->son[1]); return cur; } void del(int x){ ::rank(x); if(root->cnt > 1){ root->cnt--; root->update(); return; } node * l = pre(), *oldroot = root; splay(l); l->son[1] = oldroot->son[1]; l->son[1]->fa = l; oldroot->clear(); root->update(); } int prev(node * rt, int val){ if(rt == null)return -INF; if(val > rt->key)return max(rt->key,::prev(rt->son[1],val)); else return ::prev(rt->son[0],val); } int next(node * rt, int val){ if(rt == null)return INF; if(val < rt->key)return min( rt->key,::next(rt->son[0],val)); else return ::next(rt->son[1],val); } int main() { #ifdef LOCAL FOPEN; #endif tot = 0; null = root = &tree[0]; n = read(); insert(INF), insert(-INF); while (n--){ int op = read(), x = read(); if(op == 1){ insert(x); }else if(op == 2){ del(x); }else if(op == 3){ ff(::rank(x)); }else if(op == 4){ ff(kth(x + 1)); }else if(op == 5){ ff(::prev(root, x)); }else{ ff(::next(root,x)) } } return 0; }
天才选手zerol的主页:https://zerol.me/
|
WeepingDemon的个人主页:https://weepingdemon.gitee.io/blog/