S0CRiA @ 2021-08-29 20:15:15
//P6136
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int s = 0; char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s;
}
const int N = 1100010;
struct fhqTreap{
int ch[N][2], val[N], pri[N], siz[N], tot;
int root, x, y, z;
fhqTreap(){
srand(time(NULL));
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
memset(pri, 0, sizeof(pri));
memset(siz, 0, sizeof(siz));
tot = root = x = y = z = 0;
newnode(0xcfcfcfcf), newnode(0x3f3f3f3f);
}
void update(int x){ siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; }
int newnode(int v){ siz[++tot] = 1, val[tot] = v, pri[tot] = rand(); return tot;}
int merge(int x, int y){
if(!x || !y) return x + y;
if(pri[x] < pri[y]){ ch[x][1] = merge(ch[x][1], y), update(x); return x; }
else { ch[y][0] = merge(x, ch[y][0]), update(y); return y; }
}
void split(int now, int k, int &x, int &y){
if(!now){ x = y = 0; return; }
if(val[now] <= k) x = now, split(ch[now][1], k, ch[now][1], y);
else y = now, split(ch[now][0], k, x, ch[now][0]);
update(now);
}
int kth(int now, int k){
while(true){
if(k <= siz[ch[now][0]]) now = ch[now][0];
else if(k == siz[ch[now][0]] + 1) return now;
else k -= siz[ch[now][0]] + 1, now = ch[now][1];
}
}
void Insert(int k){
split(root, k, x, y);
root = merge(merge(x, newnode(k)), y);
}
void Delete(int k){
split(root, k, x, z);
split(x, k-1, x, y);
y = merge(ch[y][0], ch[y][1]);
root = merge(merge(x, y), z);
}
int GetRankByVal(int k){
split(root, k-1, x, y);
int ans = siz[x] + 1;
root = merge(x, y);
return ans;
}
int GetValByRank(int k){
return val[kth(root, k)];
}
int GetPre(int k){
split(root, k-1, x, y);
int ans = val[kth(x, siz[x])];
root = merge(x, y);
return ans;
}
int GetNxt(int k){
split(root, k, x, y);
int ans = val[kth(y, 1)];
root = merge(x, y);
return ans;
}
} T;
int main(){
int n, m, last = 0, ans = 0, op, x;
n = read(), m = read();
for(int i = 1; i <= n; ++ i) T.val[i] = read();
for(int i = 1; i <= m; ++ i){
op = read(), x = read() ^ last;
switch(op){
case 1: T.Insert(x); break;
case 2: T.Delete(x); break;
case 3: last = T.GetRankByVal(x); break;
case 4: last = T.GetValByRank(x); break;
case 5: last = T.GetPre(x); break;
case 6: last = T.GetNxt(x); break;
}
if(op >= 3) ans ^= last;
}
printf("%d\n", ans);
return 0;
}
fhqTreap板子能过P3369
by S0CRiA @ 2021-08-29 20:15:50
一查前驱就卡死
by liubw_ @ 2021-08-29 20:30:59
inline void spl_v(int pos,int key,int &x,int &y){ //按value大小 搜索
if(pos==0){
x=y=0;
return;
}
if(val[pos]<=key) x=pos,spl_v(rson,key,rson,y);
else y=pos,spl_v(lson,key,x,lson);
upd(pos);
}
inline void spl_r(int pos,int key,int &x,int &y){ //按子树大小搜索
if(pos==0){
x=y=0;
return;
}
if(siz[lson]<key) x=pos,spl_r(rson,key-siz[lson]-1,rson,y);
else y=pos,spl_r(lson,key,x,lson);
upd(pos);
}
inline int pre(int v){ //查询前驱
spl_v(root,v-1,x,y);
spl_r(x,siz[x]-1,x,z);
r=val[z];
root=mrg(mrg(x,z),y);
return r;
}
以上是我平衡树的部分板子
怀疑是你代码里kth()
有问题
但我没有证据
by S0CRiA @ 2021-08-29 20:33:52
@16岁 非加强版能过啊
by liubw_ @ 2021-08-29 20:35:57
@Fее_cle6418 话说我的treap还没在洛谷提交过,我自己先去试一下
by liubw_ @ 2021-08-29 21:00:05
@Fее_cle6418 @cymrain07 怀疑是非加强版数据太水了。
这里还是要认为函数有点瑕疵
by liubw_ @ 2021-08-29 21:02:21
by the way 我刚才spl_r函数的if里少了个等号
by liubw_ @ 2021-08-29 21:39:58
匪夷所思的错误,你是不是没有插入初始点
by S0CRiA @ 2021-08-29 21:56:03
@16岁 出来了,读入数组的时候不能用 T.val[i] = read();
,要 T.Insert(read());