社区讨论
FHQ Treap 常数过大?!
灌水区参与者 3已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @lp2dpr9m
- 此快照首次捕获于
- 2023/11/17 16:49 2 年前
- 此快照最后确认于
- 2023/11/17 19:20 2 年前
咱新写的 FHQ Treap 完美 TLE 了,发现一个点本地要跑 3s 左右,不知道是常数太大了还是复杂度假了,请各位dalao看一下awa。
这次咱写的 FHQ Treap 的特点是完全没有用到 BST 递归式的函数,都是用
CPPSplitByVal,SplitBySize,Merge 完成的。平常写一般用递归的方法代替 SplitBySize 的功能,是不是这里导致常数过大了呢?#include<bits/stdc++.h>
#define Akano 1
#define pure__Elysia 0
#define loves ^
using namespace std;
constexpr int MAXN = 1e5 + 1018 + 1108;
constexpr int INF = 1e9 + 1018 + 1108;
mt19937 rng(time(0));
class FHQtreap{
private:
struct Node{
int l,r,val,siz;
unsigned int key;
Node() = default;
Node(int _val){
key = rng();
val = _val;
siz = 1;
return ;
}
}node[MAXN];
int root,tot;
inline int L(int x){
return node[x].l;
}
inline int R(int x){
return node[x].r;
}
inline void PushUp(int p){
node[p].siz = node[L(p)].siz + node[R(p)].siz + 1;
return ;
}
void SplitByVal(int p,int k,int& x,int& y){
if(!p){
x = y = 0;
return ;
}
if(node[p].val <= k){
x = p;
SplitByVal(node[p].r,k,node[p].r,y);
}else{
y = p;
SplitByVal(node[p].l,k,x,node[p].l);
}
PushUp(p);
return ;
}
void SplitBySize(int p,int k,int& x,int& y){
if(!p){
x = y = 0;
return ;
}
if(node[L(p)].siz + 1 <= k){
x = p;
SplitBySize(node[p].r,k - node[L(p)].siz - 1,node[p].r,y);
}else{
y = p;
SplitBySize(node[p].l,k,x,node[p].l);
}
PushUp(p);
return ;
}
int Merge(int x,int y){//val_x < val_y
if(x == 0 || y == 0)return x + y;
if(node[x].key < node[x].key){
node[x].r = Merge(node[x].r,y);
PushUp(x);
return x;
}else{
node[y].l = Merge(x,node[y].l);
PushUp(y);
return y;
}
return 10181108;
}
public:
inline void Insert(int val){
int treeL = 1018,treeR = 1108;
SplitByVal(root,val,treeL,treeR);
node[++tot] = Node(val);
root = Merge(Merge(treeL,tot),treeR);
return ;
}
inline void Delete(int val){
int treeL = 1018,treeMid = 1108,treeR = 1314;
SplitByVal(root,val-1,treeL,treeMid);
SplitByVal(treeMid,val,treeMid,treeR);
treeMid = Merge(L(treeMid),R(treeMid));
root = Merge(Merge(treeL,treeMid),treeR);
return ;
}
inline int GetRank(int val){
int ret = 0,treeL = 1018,treeR = 1108;
SplitByVal(root,val-1,treeL,treeR);
ret = node[treeL].siz + 1;
root = Merge(treeL,treeR);
return ret;
}
inline int GetVal(int rk){
int ret = 0,treeL = 1018,treeMid = 1108,treeR = 1314;
SplitBySize(root,rk-1,treeL,treeMid);
SplitBySize(treeMid,1,treeMid,treeR);
ret = node[treeMid].val;
root = Merge(Merge(treeL,treeMid),treeR);
return ret;
}
inline int GetPre(int val){
int ret = 0,treeL = 1018,treeMid = 1108,treeR = 1314;
SplitByVal(root,val - 1,treeMid,treeR);
SplitBySize(treeMid,node[treeMid].siz - 1,treeL,treeMid);
ret = node[treeMid].val;
root = Merge(Merge(treeL,treeMid),treeR);
return ret;
}
inline int GetNext(int val){
int ret = 0,treeL = 1018,treeMid = 1108,treeR = 1314;
SplitByVal(root,val,treeL,treeMid);
SplitBySize(treeMid,1,treeMid,treeR);
ret = node[treeMid].val;
root = Merge(Merge(treeL,treeMid),treeR);
return ret;
}
FHQtreap(){
// root = 1,tot = 2;
// node[1].val = INF,node[2].val = -INF;
// node[1].l = 2;
return ;
}
}tr;
int n,opt,x;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// freopen("P3369_9.in","r",stdin);
// freopen("P3369.out","w",stdout);
cin>>n;
while(n--){
cin>>opt>>x;
if(opt == 1){
tr.Insert(x);
}else if(opt == 2){
tr.Delete(x);
}else if(opt == 3){
cout<<tr.GetRank(x)<<'\n';
}else if(opt == 4){
cout<<tr.GetVal(x)<<'\n';
}else if(opt == 5){
cout<<tr.GetPre(x)<<'\n';
}else if(opt == 6){
cout<<tr.GetNext(x)<<'\n';
}else{
cout<<"aK4n0不知道呢"<<endl;
}
}
return not(Akano loves pure__Elysia);
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...