1 条题解
-
0
#include <bits/stdc++.h> using namespace std; #define lc(p) tr[p].ls #define rc(p) tr[p].rs const int N = 3e5 + 10; struct node { int ls, rs, val, siz, rnd; } tr[N * 20]; int trlen, T, rt[N]; void pushup(int p) { tr[p].siz = tr[lc(p)].siz + tr[rc(p)].siz + 1; } int newd(node no) { tr[++trlen] = no; return trlen; } int newd(int v) { tr[++trlen] = {0, 0, v, 1, rand()}; return trlen; } // 本题按树的大小 siz 划分,可持久化 split 需要在路径上复制节点 void split(int p, int k, int &x, int &y) { if (p == 0) { x = y = 0; return; } if (tr[lc(p)].siz < k) { x = newd(tr[p]); // 复制当前节点 split(rc(p), k - tr[lc(p)].siz - 1, rc(x), y); pushup(x); } else { y = newd(tr[p]); // 复制当前节点 split(lc(p), k, x, lc(y)); pushup(y); } } int merge(int x, int y) { if (!x || !y) return x + y; if (tr[x].rnd < tr[y].rnd) { rc(x) = merge(rc(x), y); pushup(x); return x; } else { lc(y) = merge(x, lc(y)); pushup(y); return y; } } int getval(int p, int k) { if (tr[lc(p)].siz + 1 == k) return tr[p].val; if (k <= tr[lc(p)].siz) return getval(lc(p), k); else return getval(rc(p), k - tr[lc(p)].siz - 1); } int main() { int n; scanf("%d", &n); rt[0] = 0; T = trlen = 0; int x, y, z, t, k, v, op; while (n--) { scanf("%d", &op); if (op == 1) { scanf("%d%d%d", &t, &k, &v); rt[++T] = rt[t]; // 继承历史版本 split(rt[T], k - 1, x, y); rt[T] = merge(merge(x, newd(v)), y); } if (op == 2) { scanf("%d%d", &t, &k); rt[++T] = rt[t]; // 继承历史版本 // 修正后的删除逻辑: split(rt[T], k, x, y); // x 包含前 k 个元素,y 包含第 k+1 个及以后的元素 split(x, k - 1, x, z); // x 包含前 k-1 个元素,z 为第 k 个元素(将被丢弃) rt[T] = merge(x, y); // 合并前 k-1 个和剩余部分,实现删除 } if (op == 3) { scanf("%d%d", &t, &k); printf("%d\n", getval(rt[t], k)); } } return 0; }#include<bits/stdc++.h> using namespace std; #define lc(p) tr[p].ls #define rc(p) tr[p].rs const int N=3e5+10; struct node{int ls,rs,val,siz,rnd;}tr[N*20];int trlen,T,rt[N]; void pushup(int p){tr[p].siz=tr[lc(p)].siz+tr[rc(p)].siz+1;} int newd(node no){tr[++trlen]=no; return trlen; } int newd(int v){tr[++trlen]={0,0,v,1,rand()}; return trlen; } void split(int p,int k,int &x,int &y)//本题按树的大小siz划分 { if(p==0){x=y=0;return ;} if(tr[lc(p)].siz<k) { x=newd(tr[p]); split(rc(p),k-tr[lc(p)].siz-1,rc(x),y); pushup(x); } else { y=newd(tr[p]); split(lc(p),k,x,lc(y)); pushup(y); } } int merge(int x,int y) { if(!x||!y) return x+y; if(tr[x].rnd<tr[y].rnd) { rc(x)=merge(rc(x),y); pushup(x); return x; } else { lc(y)=merge(x,lc(y)); pushup(y); return y; } } int getval(int p,int k) { if(tr[lc(p)].siz+1==k) return tr[p].val; if(k<=tr[lc(p)].siz) return getval(lc(p),k); else return getval(rc(p),k-tr[lc(p)].siz-1); } int main() { int n;scanf("%d",&n); rt[0]=0;T=trlen=0; int x,y,z,t,k,v,op; while(n--) { scanf("%d",&op); if(op==1) { scanf("%d%d%d",&t,&k,&v);rt[++T]=rt[t]; split(rt[T],k-1,x,y); rt[T]=merge(merge(x,newd(v)),y); } if(op==2) { scanf("%d%d",&t,&k);rt[++T]=rt[t]; split(rt[T],k,x,y); split(x,k-1,x,z); rt[T]=merge(x,y); } if(op==3) { scanf("%d%d",&t,&k); printf("%d\n",getval(rt[t],k)); } } return 0; }
- 1
信息
- ID
- 523
- 时间
- 1500ms
- 内存
- 768MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 260
- 已通过
- 35
- 上传者