华中区全国程序设计邀请赛1003

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

这题是在比赛的过程中完成的,是一道线段树问题,我当时写了好久,感觉跟普通的线段树不一样,

因为本来自己对线段树的理解就不是很透彻,所以写起来很困难,不过我最后还是把这个问题解决了,

使自己对线段树的理解又加深了一层。代码如下:

#include"stdio.h"





__int64 sum;

struct ln

{

    int left,right,num;

}nod[800000];





void create(int u,int l,int r)

{

    int mid;

    nod[u].left=l;nod[u].right=r;

    if(l==r)

    {

        nod[u].num=1;

        return ;

    }

    mid=(l+r)>>1;

    create(u+u,l,mid);

    create(u+u+1,mid+1,r);

    nod[u].num=nod[u+u].num+nod[u+u+1].num;

}



void change(int u,int order,int k)

{

    order-=nod[u].num;

    if(nod[u].left==nod[u].right)

    {

        sum+=nod[u].left;

        nod[u].num--;

        return ;

    }

    else

    {

        if(order+nod[u+u].num>=k)

            change(u+u,order+nod[u+u].num,k);

        else 

            change(u+u+1,order+nod[u+u].num+nod[u+u+1].num,k);

    }

    nod[u].num--;

}



int main( )

{

    int t,n,k,ki,i,count=1;

    scanf("%d",&t);

    while(t--)

    {

        sum=0;

        scanf("%d%d",&n,&k);

        create(1,1,n);

        for(i=1;i<=k;i++)

        {

            scanf("%d",&ki);

            change(1,nod[1].num,ki);

        }

        printf("Case %d: ",count++);

        printf("%I64d\n",sum);

    }

    return 0;

}

 

你可能感兴趣的:(程序设计)