hdu 4217

想了很久,才知道用线段树来做,实现也不算太复杂。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define SIZE 262145
struct node
{
    int i,left,right,sum;
};
node vert[SIZE<<2];
int treeNode;
int build(int i,int left,int right)
{
    int mid;
    vert[i].left=left;
    vert[i].right=right;
    vert[i].sum=right-left+1;
    if(left==right)
    {
        vert[i].i=++treeNode;
        return 0;
    }

    mid=(left+right)>>1;
    build(i<<1,left,mid);
    build((i<<1)+1,mid+1,right);

    return 0;
}
int query(int i,int n,int goal)
{
    int res;
    if(vert[i].left==vert[i].right)
    {
        vert[i].sum=0;
        return vert[i].i;
    }

    if(goal <= vert[i<<1].sum)  
    {
        res = query(i<<1,n,goal);
    }
    else
    {
        res = query((i<<1)+1,n,goal-vert[i<<1].sum);
    }
    vert[i].sum--;
    return res;
}
int main()
{
    int i,k,m,n,inum,count=0;
    __int64 sum;
    scanf("%d",&inum);
    while(inum--)
    {
        count++; sum=0; treeNode=0;
        scanf("%d %d",&n,&m);
        build(1,1,n);
        for(i=0;i<m;i++)
        {
            scanf("%d",&k);
            sum+=query(1,n,k);
        }
        printf("Case %d: %I64d\n",count,sum);
    }
    return 0;
}
posted @ 2012-04-18 19:13  书山有路,学海无涯  阅读(359)  评论(0编辑  收藏  举报