题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795
线段树问题:
思路:当前访问的结点的最大值小于给定值,直接返回-1。否则,左子树的最大值大于当前值,那么访问左子树,
小于则访问右子树,直到叶子结点结束。其中h=min(h,n) (RE两次, >.<...........)
#include<iostream> #include<cstdio> using namespace std; #define N 200010 #define L(a) ((a)<<1) #define R(a) ((a)<<1|1) struct node { int l,r,Max; }line[N*3]; int h,w,n; void create(int k,int x,int y) { line[k].l=x;line[k].r=y; line[k].Max=w; if(x==y) return; int mid=(x+y)>>1; create(L(k),x,mid); create(R(k),mid+1,y); } int mymax(int a,int b) { return a>b?a:b; } int updata(int k,int val) { if(line[k].l==line[k].r) { if(val>line[k].Max) return -1; line[k].Max-=val; return line[k].l; } if(val<=line[k].Max) { int x=0; if(val<=line[L(k)].Max) x=updata(L(k),val); else x=updata(R(k),val); line[k].Max=mymax(line[L(k)].Max,line[R(k)].Max); return x; } else return -1; } int main() { int i,temp; while(scanf("%d%d%d",&h,&w,&n)!=EOF) { if(h>n) h=n; create(1,1,h); for(i=1;i<=n;i++) { scanf("%d",&temp); printf("%d\n",updata(1,temp)); } } return 0; }