洛谷P3369 普通平衡樹
阿新 • • 發佈:2019-02-06
用權值線段樹來做 要先離散化
#include<cstdio> #include<iostream> #include<cctype> #include<algorithm> using namespace std; #define int long long #define ls (o<<1) #define rs (ls|1) int b[100500]; int a[100500]; int val[100500]; int st[405000]; int n; int tot; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9) put(x/10); putchar(x%10+'0'); } inline void add_or_del(int o,int l,int r,int k,int pos) { st[o]+=pos; if(l==r) return; int mid=(l+r)>>1; if(k<=mid) add_or_del(ls,l,mid,k,pos); else add_or_del(rs,mid+1,r,k,pos); } inline int x_rank_n(int o,int l,int r,int k) { if(l==r) return 1; int mid=(l+r)>>1; if(k<=mid) return x_rank_n(ls,l,mid,k); else return st[ls]+x_rank_n(rs,mid+1,r,k); } inline int n_rank_x(int o,int l,int r,int k) { if(l==r) return l; int mid=(l+r)>>1; if(st[ls]>=k) return n_rank_x(ls,l,mid,k); else return n_rank_x(rs,mid+1,r,k-st[ls]); } signed main() { n=read(); for(int i=1;i<=n;i++) { val[i]=read(); a[i]=read(); if(val[i]!=4) b[++tot]=a[i]; } sort(b+1,b+tot+1); for(int i=1;i<=n;i++) { if(val[i]!=4) a[i]=lower_bound(b+1,b+tot+1,a[i])-b; } for(int i=1;i<=n;i++) { switch(val[i]) { case 1: add_or_del(1,1,tot,a[i],1);break; case 2: add_or_del(1,1,tot,a[i],-1);break; case 3: put(x_rank_n(1,1,tot,a[i]));putchar('\n');break; case 4: put(b[n_rank_x(1,1,tot,a[i])]);putchar('\n');break; case 5: put(b[n_rank_x(1,1,tot,x_rank_n(1,1,tot,a[i])-1)]);putchar('\n');break; default: put(b[n_rank_x(1,1,tot,x_rank_n(1,1,tot,a[i]+1))]);putchar('\n'); } } return 0; }