【題解】Luogu P3871 [TJOI2010]中位數
阿新 • • 發佈:2018-11-17
平衡樹板題
原題傳送門
這道題要用Splay,我部落格裡有對Splay的詳細介紹
每次加入一個數,把數插入平衡樹中
並且要記錄一共有多少個數
每次查詢就查詢平衡樹中第(總數-1)/2+1個數
十分暴力
#include <bits/stdc++.h> #define N 110005 #define root tree[0].ch[1] using namespace std; inline int read() { register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f; } inline void write(register int x) { if(!x)putchar('0');if(x<0)x=-x,putchar('-'); static int sta[36];int tot=0; while(x)sta[tot++]=x%10,x/=10; while(tot)putchar(sta[--tot]+48); } struct splay{ int v,fa,ch[2],rec,sum; }tree[N]; int tot=0; inline bool findd(register int x) { return x==tree[tree[x].fa].ch[0]?0:1; } inline void connect(register int x,register int fa,register int son) { tree[x].fa=fa; tree[fa].ch[son]=x; } inline void update(register int x) { tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec; } inline void rotate(register int x) { int Y=tree[x].fa; int R=tree[Y].fa; int Yson=findd(x); int Rson=findd(Y); int B=tree[x].ch[Yson^1]; connect(B,Y,Yson); connect(Y,x,Yson^1); connect(x,R,Rson); update(Y),update(x); } inline void splay(register int x,register int to) { to=tree[to].fa; while(tree[x].fa!=to) { int y=tree[x].fa; if(tree[y].fa==to) rotate(x); else if(findd(x)==findd(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } } inline int newpoint(register int v,register int fa) { tree[++tot].v=v; tree[tot].fa=fa; tree[tot].sum=tree[tot].rec=1; return tot; } inline void Insert(register int x) { int now=root; if(root==0) { newpoint(x,0); root=tot; } else { while(19260817) { ++tree[now].sum; if(x==tree[now].v) { ++tree[now].rec; splay(now,root); return; } int nxt=x<tree[now].v?0:1; if(!tree[now].ch[nxt]) { int p=newpoint(x,now); tree[now].ch[nxt]=p; splay(p,root); return; } now=tree[now].ch[nxt]; } } } inline int arank(register int x) { int now=root; while(19260817) { int used=tree[now].sum-tree[tree[now].ch[1]].sum; if(x>tree[tree[now].ch[0]].sum&&x<=used) { splay(now,root); return tree[now].v; } if(x<used) now=tree[now].ch[0]; else x-=used,now=tree[now].ch[1]; } } int main() { int n=read(); int sum=0; for(register int i=1;i<=n;++i) { int x=read(); Insert(x); ++sum; } int m=read(); while(m--) { char ch=getchar(); while(ch!='a'&&ch!='m') ch=getchar(); if(ch=='a') { int x=read(); Insert(x); ++sum; } else if(ch=='m') { write(arank((sum-1)/2+1)); printf("\n"); } } return 0; }