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;
}


原文地址:https://www.cnblogs.com/riskyer/p/3249162.html