代码依然参考胡浩神:
说说思路吧,因为n最大有20W,所以可以把每一行当作线段树的叶子(因为n可能小于h,所以只需要最小的那个建树就可以了),每一个叶子的值则是w;
要保证 announcements 是贴在最上面的,而且是最左边的(这点无需考虑,因为是按照读入的顺序来的),要保证是贴在最上面,所以优先向左子树搜索,即当前结点的左子树值(代表左子树下有叶子的值是大于wi的)大于wi,就搜索左子树,这样只要在搜索出来的时候直接更新就可以了......
不得不说代码相似度和胡浩神的到了100% 你妹 我真是自己敲的啊!!
#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <string.h>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <ctime>
#include <map>
#include <limits>
#define LL long long
#define Vi vector<int>
#define Si set<int>
#define readf freopen("input.txt","r",stdin)
#define writef freopen("output.txt","w",stdout)
#define FF(i,a) for(int i(0); i < (a); i++)
#define FD(i,a) for(int i(a); i >= (1); i--)
#define FOR(i,a,b) for(int i(a);i <= (b); i++)
#define FOD(i,a,b) for(int i(a);i >= (b); i--)
#define PD(a) printf("%d",a)
#define SET(a,b) memset(a,b,sizeof(a))
#define SD(a) scanf("%d",&(a))
#define LN printf("\n")
#define PS printf(" ")
#define pb push_back
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const double pi = acos(-1.0);
const int maxn = 200001;
const int INF = 99999999;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
using namespace std;
int W,H,N;
int Max[maxn<<2];
void PushUP(int rt){
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt){
Max[rt]=W;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
int query(int x,int l,int r,int rt){ // ym hh神 结合的太巧妙了,自己绝对想不到
if(l==r){
Max[rt]-=x;
return r;
}
int m=(l+r)>>1;
int ret=(Max[rt<<1] >=x ) ? query(x,lson):query(x,rson);
PushUP(rt);
return ret;
}
int main()
{
while (~scanf("%d%d%d",&H,&W,&N)) {
if (H > N) H = N;
build(1 , H , 1);
while (N--) {
int x;
scanf("%d",&x);
if (Max[1] < x) puts("-1");
else printf("%d\n",query(x , 1 , H , 1));
}
}
return 0;
}