先建树,
val只有根节点存数的值。
nsum表示该子树还剩多少个数;
del(1,x);
要从树中删掉第x个数,,先看跟的左子树的nsum,,
如果x<=nsum,则从左子树中删掉第x个数,
否则,在右子树中删掉第x-nsum个数。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 270000
#define ll __int64
struct node{
int l,r,nsum;
ll val;
}tree[3*N];
ll sum;
void build(int id,int x,int y)
{
tree[id].l=x;
tree[id].r=y;
if(x==y)
{
tree[id].nsum=1;
tree[id].val=x;
return ;
}
int mid=(x+y)>>1;
build(id<<1,x,mid);
build((id<<1)+1,mid+1,y);
tree[id].nsum=tree[id<<1].nsum+tree[(id<<1)+1].nsum;
}
void del(int id,int x)
{
if(tree[id].l==tree[id].r && x==1){
sum+=tree[id].val;
tree[id].nsum=0;
return ;
}
if(tree[id<<1].nsum<x)
{
del((id<<1)+1,x-tree[id<<1].nsum);
tree[id].nsum-=1;
}
else
{
del(id<<1,x);
tree[id].nsum-=1;
}
}
int main()
{
int t;
scanf("%d",&t);
int ans=0;
while(t--){
ans++;
printf("Case %d: ",ans);
int n,k,i,j,h;
scanf("%d%d",&n,&k);
build(1,1,n);
sum=0;
while(k--)
{
scanf("%d",&h);
del(1,h);
}
printf("%I64d\n",sum);
}
}