http://acm.hdu.edu.cn/showproblem.php?pid=4217

经典的线段树问题,找第k小数。

注意sum用__int64

View Code
#include <stdio.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=300000;
int tree[maxn<<2];
int temp;
void build(int l,int r,int rt)
{
    tree[rt]=r-l+1;
    if(l==r)
        return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void dele(int del,int l,int r,int rt)
{
    tree[rt]--;
    if(l==r){
        temp=l;
        return;
    }
    int m=(l+r)>>1;
    if(del<=tree[rt<<1])dele(del,lson);
    else{
        del-=tree[rt<<1];
        dele(del,rson);
    } 
}
int main()
{
    int t,n,k,ki,i;
    int nCase=1;
    __int64 sum;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        build(1,n,1);
        sum=0;
        for(i=0;i<k;i++)
        {
            scanf("%d",&ki);
            dele(ki,1,n,1);
            sum+=temp;
        }
        printf("Case %d: %I64d\n",nCase++,sum);
    }
    return 0;
}