gym 101064 G.The Declaration of Independence (主席樹)
阿新 • • 發佈:2018-09-06
直接 兩個 enc upd () class 我們 lar 元素
題目鏈接:
題意:
n個操作,有兩種操作:
E p c 在序號為p的隊列尾部插入c得到新的隊列,序號為i
D p 查詢並刪除序號為p的隊列頂部的元素,得到序號為i的新隊列
思路:
需要查詢歷史版本,我們可以用將這些操作都更新在主席樹上,這兩個操作可以等價為更新一個點,查詢一個點,尾部和頂部的元素我們可以分別用l[i],r[i]來維護第i個隊列的頂部元素和尾部元素,查詢的時候直接在主席樹上找就好了。
實現代碼:
#include<iostream> #include<cstdio> using namespace std; #definelson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 1e5+10; int ls[M*40],rs[M*40],sum[M*40],idx,root[M]; void update(int old,int &rt,int p,int c,int l,int r){ rt = ++idx; ls[rt] = ls[old]; rs[rt] = rs[old]; sum[rt] = sum[old];if(l == r){ sum[rt] = c; return ; } mid; if(p <= m) update(ls[old],ls[rt],p,c,l,m); else update(rs[old],rs[rt],p,c,m+1,r); } int query(int p,int l,int r,int rt){ if(l == r) return sum[rt]; mid; if(p <= m) return query(p,l,m,ls[rt]);else return query(p,m+1,r,rs[rt]); } int n,p,c; char op[5]; int l[M],r[M]; int main() { idx = 0; l[0] = 1;r [0] = 0; scanf("%d",&n); for(int i = 1;i <= n;i ++){ scanf("%s",op); if(op[0] == ‘E‘){ scanf("%d%d",&p,&c); l[i] = l[p]; r[i] = r[p]; update(root[p],root[i],++r[i],c,1,n); } else { scanf("%d",&p); l[i] = l[p]; r[i] = r[p]; root[i] = root[p]; printf("%d\n",query(l[i]++,1,n,root[i])); } } return 0; }
gym 101064 G.The Declaration of Independence (主席樹)