Warriors_Cat @ 2020-04-04 21:00:08
RT
成功从 80 分变成了 90 分
呜呜呜大家能帮我看看卡卡常吗,含注释的哦-v-。
下面是代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
const int INF = 0x7fffffff, N = 1100050;
int siz[N], son[N][2], cnt[N], pri[N], val[N], num, Root, ans, lst, opt, x, n, m;//一堆乱七八糟不知所云的变量
inline int new_node(int x){val[++num] = x; pri[num] = rand(); cnt[num] = siz[num] = 1; return num;}//新建节点
inline void pushup(int x){siz[x] = siz[son[x][0]] + siz[son[x][1]] + cnt[x];}//维护子树大小
inline void Rotate(int &x, int id){
int y = son[x][id ^ 1];
son[x][id ^ 1] = son[y][id];
son[y][id] = x;
x = y;
pushup(son[x][id]);
pushup(x);
}//旋转
inline void Insert(int &x, int key){
if(!x){x = new_node(key); return;}
if(val[x] == key){cnt[x]++; siz[x]++; return;}
int id = key < val[x] ? 0 : 1;
Insert(son[x][id], key);
if(pri[x] < pri[son[x][id]]) Rotate(x, id ^ 1);
pushup(x);
return;
}//插入
inline void Delete(int &x, int key){
if(!x) return;
if(key == val[x]){
if(cnt[x] > 1){
cnt[x]--;
pushup(x);
return;
}
if(son[x][0] || son[x][1]){
if(!son[x][1] && pri[son[x][0]] > pri[son[x][1]]){
Rotate(x, 1);
Delete(son[x][1], key);
}
else{
Rotate(x, 0);
Delete(son[x][0], key);
}
pushup(x);
}
else x = 0;
return;
}
if(key < val[x]) Delete(son[x][0], key);
else Delete(son[x][1], key);
pushup(x);
return;
}//删除
inline int Pre(int key){
int x = Root, ans = -INF;
while(x){
if(val[x] < key) ans = val[x], x = son[x][1];
else x = son[x][0];
}
return ans;
}//前驱
inline int Suf(int key){
int x = Root, ans = INF;
while(x){
if(val[x] > key) ans = val[x], x = son[x][0];
else x = son[x][1];
}
return ans;
}//后继
inline int Find(int x, int key){
if(!x) return 1;
if(key == val[x]) return siz[son[x][0]] + 1;
else if(key < val[x]) return Find(son[x][0], key);
else return siz[son[x][0]] + cnt[x] + Find(son[x][1], key);
}//已知值求排名
inline int Rank(int x, int k){
if(!x) return 0;
if(k <= siz[son[x][0]]) return Rank(son[x][0], k);
else if(k <= siz[son[x][0]] + cnt[x]) return val[x];
else return Rank(son[x][1], k - siz[son[x][0]] - cnt[x]);
}//已知排名求值
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i){
scanf("%d", &x);
Insert(Root, x);
}
for(int i = 1; i <= m; ++i){
scanf("%d%d", &opt, &x);
x ^= lst;
if(opt == 1) Insert(Root, x);
if(opt == 2) Delete(Root, x);
if(opt == 3) lst = Find(Root, x), ans ^= lst;
if(opt == 4) lst = Rank(Root, x), ans ^= lst;
if(opt == 5) lst = Pre(x), ans ^= lst;
if(opt == 6) lst = Suf(x), ans ^= lst;
}
printf("%d", ans);
return 0;
}
呜呜呜
by Skyjoy @ 2020-04-04 21:04:36
@蒟蒻的名字 xcy对不起我只会Splay啊QAQ
by btng_smith666 @ 2020-04-04 21:07:40
不会,下一个
by 谋事在人 @ 2020-04-04 21:11:09
treap不应该被卡常啊?不是splay都很轻松吧洛谷O2,八聚氧,火车头
by Hexarhy @ 2020-04-04 21:13:36
@蒟蒻的名字 如果是卡常的话
用快读吧
by Warriors_Cat @ 2020-04-04 21:43:27
@Hilarious_Reality 通过了,谢谢-v-
by __Watcher @ 2020-04-04 21:51:46
@蒟蒻的名字 你可以弄一个 srand 来设定种子。嗯,我设成 1314 就过了。