rt。在下方完整代码的 18 行,给节点随机赋权值的时候,我写了两种写法:
//写法一
tree[p].val = rd();
//写法二
tree[p].val = rd()%114514;
唯一区别在于取模。但是写法一样例第 3 个输出随机抽风为 4,写法二却没事。
没开 long long,随机数用的是 mt19937。其它平衡树我是按照写法一写的,没抽过风,今天是第一次。问佬是什么原因?建议用哪种写法?
完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,ntot = 0,root;
mt19937 rd(time(0));
stack<int> que;
bitset<50005> used;
struct node{
int ls,rs,key,val,s;
}tree[50005];
void push_up(int p){
tree[p].s = tree[tree[p].ls].s+tree[tree[p].rs].s+1;
return;
}
int addnode(int key){
int p = ++ntot;
tree[p].ls = tree[p].rs = 0;
tree[p].key = key;
tree[p].val = rd()%114514;
tree[p].s = 1;
return p;
}
void build(){
addnode(0),addnode(n+1);
root = 1;
tree[1].rs = 2;
push_up(1);
return;
}
void zig(int &p){
int q = tree[p].ls;
tree[p].ls = tree[q].rs,tree[q].rs = p,p = q;
push_up(tree[p].rs),push_up(p);
return;
}
void zag(int &p){
int q = tree[p].rs;
tree[p].rs = tree[q].ls,tree[q].ls = p,p = q;
push_up(tree[p].ls),push_up(p);
return;
}
void add(int &p,int key){
if(!p){
p = addnode(key);
}else{
if(tree[p].key > key){
add(tree[p].ls,key);
if(tree[tree[p].ls].val > tree[p].val){
zig(p);
}
}else{
add(tree[p].rs,key);
if(tree[tree[p].rs].val > tree[p].val){
zag(p);
}
}
}
push_up(p);
return;
}
void del(int &p,int key){
if(!p){
return;
}
if(tree[p].key == key){
if(tree[p].ls || tree[p].rs){
if(!tree[p].rs || tree[tree[p].ls].val > tree[tree[p].rs].val){
zig(p);
del(tree[p].rs,key);
}else{
zag(p);
del(tree[p].ls,key);
}
}else{
p = 0;
}
}else{
if(tree[p].key > key){
del(tree[p].ls,key);
}else{
del(tree[p].rs,key);
}
}
push_up(p);
return;
}
int getprev(int p,int key){
if(!p){
return 0;
}
if(tree[p].key > key){
return getprev(tree[p].ls,key);
}else{
return max(tree[p].key,getprev(tree[p].rs,key));
}
}
int getnext(int p,int key){
if(!p){
return n+1;
}
if(tree[p].key < key){
return getnext(tree[p].rs,key);
}else{
return min(tree[p].key,getnext(tree[p].ls,key));
}
}
int main(){
scanf("%d%d",&n,&m);
build();
while(m--){
static char tpa;
static int tpb;
scanf(" %c",&tpa);
if(tpa == 'R'){
if(que.size()){
del(root,que.top());
used[que.top()] = 0;
que.pop();
}
continue;
}
scanf("%d",&tpb);
if(tpa == 'D'){
add(root,tpb);
used[tpb] = 1;
que.push(tpb);
}
if(tpa == 'Q'){
if(used[tpb]){
puts("0");
}else{
printf("%d\n",getnext(root,tpb)-getprev(root,tpb)-1);
}
}
}
return 0;
}