1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int N=100001; const int M=35000*3+N; struct chair { int ls,rs,sum; } T[M*40]; struct oper { int op,x,y,k; } op[M]; int root[N],A[N]; long long ans[4];
int index; int update(int rt,int l,int r,int x) { int newroot=++index; T[newroot]=T[rt]; T[newroot].sum++; if (l==r) return newroot; int m=l+r>>1; if (x<=m) T[newroot].ls=update(T[newroot].ls,l,m,x); else T[newroot].rs=update(T[newroot].rs,m+1,r,x); return newroot; }
int query(int x,int y,int l,int r,int k) { if (l==r) return l; int m=l+r>>1; int lsz=T[T[y].ls].sum-T[T[x].ls].sum; if (lsz>=k) { return query(T[x].ls,T[y].ls,l,m,k); } else { return query(T[x].rs,T[y].rs,m+1,r,k-lsz); } }
int getrank(int rt,int l,int r,int L,int R) { if (L<=l&&r<=R) return T[rt].sum; int m=l+r>>1; int res=0; if (L<=m) res+=getrank(T[rt].ls,l,m,L,R); if (m<R) res+=getrank(T[rt].rs,m+1,r,L,R); return res; }
void case_init() { index=root[0]=0; T[0].ls=T[0].rs=T[0].sum=0; memset(ans,0,sizeof(ans)); }
int main() { int cas=0; int q; while (scanf("%d",&q)!=EOF) { int n=0; case_init(); for (int i=1;i<=q;i++) { char s[10]; scanf("%s",s); if (s[0]=='I') { op[i].op=0; scanf("%d",&op[i].x); A[++n]=op[i].x; } else if (s[6]=='1') { op[i].op=1; scanf("%d%d%d",&op[i].x,&op[i].y,&op[i].k); } else if (s[6]=='2') { op[i].op=2; scanf("%d",&op[i].x); } else if (s[6]=='3') { op[i].op=3; scanf("%d",&op[i].k); } } sort(A+1,A+1+n); int tot=0; for (int i=1;i<=q;i++) { if (op[i].op==0) { tot++; root[tot]=update(root[tot-1],1,n,lower_bound(A+1,A+1+n,op[i].x)-A); } else { long long tmp=0; if (op[i].op==1) tmp=A[query(root[op[i].x-1],root[op[i].y],1,n,op[i].k)]; if (op[i].op==2) tmp=getrank(root[tot],1,n,1,lower_bound(A+1,A+1+n,op[i].x)-A); if (op[i].op==3) tmp=A[query(root[0],root[tot],1,n,op[i].k)]; ans[op[i].op]+=tmp; } } printf("Case %d:\n",++cas); for (int i=1;i<4;i++) printf("%lld\n",ans[i]); } }
|