hdu2795线段树

//===========================================

//segment tree

//final version

//by kevin_samuel(fenice)

//以h离散化构建线段树

#include <iostream>

#include <cstdio>

#include <cmath>





using namespace std;



#define MAXN 201050

#define INF 0x3fffffff





int h,w,n;

int A[MAXN];

//int max;

//int min;



struct node

{

    int left;

    int right;

    int max;

}Tree[MAXN<<2];





void maintain(int root)

{

    int LC = root<<1;

    int RC = (root<<1)+1;

    Tree[root].max = max(Tree[LC].max,Tree[RC].max);

}



void Build(int root,int start,int end)

{

    Tree[root].left = start;

    Tree[root].right = end;

    if(start == end)

    {

        Tree[root].max = w;

        return;

    }

    int mid = (start + end)>>1;

    Build(root<<1,start,mid);

    Build((root<<1)+1,mid+1,end);

    maintain(root);

}



void update(int root,int pos,int value)

{

    if(Tree[root].left == Tree[root].right)

    {

        Tree[root].max -= value;

        return;

    }

    int mid = (Tree[root].left + Tree[root].right)>>1;

    if(pos <= mid)

        update(root<<1,pos,value);

    else

        update((root<<1)+1,pos,value);

    maintain(root);

}





int Query(int root,int start,int end,int value)

{

    if(Tree[root].max < value)

        return -1;

    if(start == end)

        return start;

    int mid = (start + end)>>1;

    if(Tree[root<<1].max >= value)

        return Query(root<<1,start,mid,value);

    else

        return Query(root<<1|1,mid+1,end,value);

    

}







int main()

{

    while(scanf("%d%d%d",&h,&w,&n)!=EOF)

    {

        int hh = min(h,n);

        Build(1,1,hh);

        for(int i = 1; i <= n; i++)

        {

            scanf("%d",&A[i]);

            int ans = Query(1,1,hh,A[i]);

            cout<<ans<<endl;

            if(ans != -1)

                 update(1,ans,A[i]);

        }

    }

    return 0;

}


你可能感兴趣的:(HDU)