线段树维护该区间有多少个数就好,计算名次时二分一下。
#include <stdio.h>
#define maxn 362144
int tree[4*maxn];
void pushup(int o)
{
tree[o]=tree[o*2]+tree[o*2+1];
}
void build(int l,int r,int o)
{
if(l==r)
{
tree[o]=1;
return ;
}
int m=(l+r)/2;
build(l,m,o*2);
build(m+1,r,o*2+1);
pushup(o);
}
int query(int p,int l,int r,int o)
{
if(l==r)
{
tree[o]=0;
return l;
}
int ans;
int m=(l+r)/2;
if(tree[o*2]>=p) ans=query(p,l,m,2*o);
else ans=query(p-tree[o*2],m+1,r,2*o+1);
pushup(o);
return ans;
}
int main()
{
int t;
int n,k;
int i,x;
int cas=0;
scanf("%d",&t);
while(t--)
{
cas++;
scanf("%d%d",&n,&k);
build(1,n,1);
__int64 tot=0;
for(i=1;i<=k;i++)
{
scanf("%d",&x);
tot+=query(x,1,n,1);
}
printf("Case %d: %I64d\n",cas,tot);
}
return 0;
}