充分利用下标的资源,tree[]表示节点含有的数据个数
#include <stdio.h> const int MAXN=262144; int tree[MAXN<<1]; int pos; void build(int l,int r,int rt) { tree[rt]=r-l+1;//表示节点含有的数据个数 if(r==l) return ; int m=(r+l)/2; build(l,m,rt*2); build(m+1,r,rt*2+1); } void update(int p,int l,int r,int rt) { tree[rt]--;//更新节点的数的个数 if(r==l) { pos=l;//此时的pos代表第几个最小值 return ; } int m=(r+l)/2; if(p<=tree[rt*2])//搜索所需改变的节点 update(p,l,m,rt*2); else { p-=tree[rt*2]; update(p,m+1,r,rt*2+1); } } int main() { int t,k,n,ks,tn=1; __int64 sum; scanf("%d",&t); while(t--) { sum=0; scanf("%d%d",&n,&k); build(1,n,1); for(int i=0;i<k;i++) { scanf("%d",&ks); update(ks,1,n,1); sum+=pos; } printf("Case %d: %I64d\n",tn++,sum); } return 0; }