华中区全国程序设计邀请赛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;
}
原文地址:https://www.cnblogs.com/chaosheng/p/2450943.html