标签:mes iostream pre std ios get define algorithm include
解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #include<vector> using namespace std; typedef long long ll; const double alpha=0.7; const int N=1e5+500; int n; namespace ScapegoatTree { struct node { int l,r,v,sz,valid; bool del; void New(int x) {l=r=0;v=x;sz=valid=1;del=0;} }t[N<<2]; #define ls(o) t[o].l #define rs(o) t[o].r #define pb push_back int tot=0,rt=0; bool Bad(int o){ return (double)t[ls(o)].sz>alpha*t[o].sz||(double)t[rs(o)].sz>alpha*t[o].sz; } void Updata(int o){ t[o].sz=t[ls(o)].sz+t[rs(o)].sz+1; t[o].valid=t[ls(o)].valid+t[rs(o)].valid+!t[o].del; } void Dfs(int o,std::vector<int> &v) { if(!o) return; Dfs(ls(o),v); if(!t[o].del) v.pb(o); Dfs(rs(o),v); } int Build(std::vector<int> &v,int l,int r) { if(l>=r) return 0; int mid=(l+r)>>1; int o=v[mid]; ls(o)=Build(v,l,mid); rs(o)=Build(v,mid+1,r); Updata(o); return o; } void ReBuild(int &o) { std::vector<int>v; Dfs(o,v); o=Build(v,0,(int)v.size()); } void Insert(int x,int &o) { if(!o){ o=++tot; t[o].New(x); return ; } t[o].sz++;t[o].valid++; if(x>=t[o].v) Insert(x,rs(o)); else Insert(x,ls(o)); if(Bad(o)) ReBuild(o); return ; } void Delete(int o,int Rnk) { if(!t[o].del&&Rnk==t[ls(o)].valid+1) { t[o].del=1; --t[o].valid; return ; } --t[o].valid; if(Rnk<=t[ls(o)].valid+!t[o].del) Delete(ls(o),Rnk); else Delete(rs(o),Rnk-t[ls(o)].valid-!t[o].del); } int GetRank(int o,int x) { int ans=1; while(o) { if(t[o].v>=x) o=ls(o); else { ans+=t[ls(o)].valid+!t[o].del; o=rs(o); } } return ans; } int FindKth(int o,int x) { while(o) { if(!t[o].del&&t[ls(o)].valid+1==x) {return t[o].v;} if(t[ls(o)].valid>=x) o=ls(o); else { x-=t[ls(o)].valid+!t[o].del; o=rs(o); } } } } using namespace ScapegoatTree; int main() { scanf("%d",&n); rt=0; while(n--) { int op,x; scanf("%d%d",&op,&x); if(op==1) Insert(x,rt); if(op==2) Delete(rt,GetRank(rt,x)); if(op==3) printf("%d\n",GetRank(rt,x)); if(op==4) printf("%d\n",FindKth(rt,x)); if(op==5) printf("%d\n",FindKth(rt,GetRank(rt,x)-1)); if(op==6) printf("%d\n",FindKth(rt,GetRank(rt,x+1))); } return 0; }
标签:mes iostream pre std ios get define algorithm include
原文地址:https://www.cnblogs.com/elpsycongroo/p/10375214.html