ACM-ICPC 2018 南京赛区网络预赛 G Lpl and Energy-saving Lamps
题意:
有n个房间,每个房间有k[i]栈台灯。现在你要把所有房间的台灯换成新的节能台灯
你在每个月一开始会买m栈节能台灯。
换台灯的规则是先从列表上的第一个房间开始,如果当前房间的台灯数量<你拥有的节能台灯的数量,
那么就全部把他换掉,同时把这个房间从列表上清除。否则的话就跳过这个房间,进入下一个房间。
直到你手里的节能台灯数量为0,或者是所有在列表上的房间都遍历过一遍,那么这个月的任务就结束。
你剩余的节能台灯在下一个月还可以使用。如果某个月结束后,所有房间都换过了,那么你就不会再取买
节能台灯了
q个询问,每一个询问一个di,问你在di月结束的时候,你换了几个房间,手里剩余多少节能台灯
n<=1e5,m<=100,di<=1e5,ki<=1e4,q<=1e5
解析:
这里我是直接正面求解,模拟每一次换台灯的过程。
换完一个房间j,换下一个房间,就是在[j+1,n]里面找第一个小于当前节能台灯数量money的房间,
然后我就是用线段树来模拟的,维护区间最小值,查询的时候加一些剪枝(不然会T)
因为每一个房间只会被删除一次,那么时间复杂度接近为O(nlogn)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define Min(a,b) a>=b?b:a;
#define Max(a,b) a>=b?a:b;
const int MAXN = 1e5+100;
const int INF = 0x3f3f3f3f;
int b[MAXN];
char str[10];
#define lch root<<1
#define rch (root<<1)|1
typedef long long ll;
typedef struct node
{
int ans;
int minn;
int pos;
}node;
node Btree[MAXN*5];
int res[MAXN][2];
inline void push_up(int root)
{
/*if(Btree[lch].minn>Btree[rch].min