题意
有一个模特,她有一个初始rating值 s。她每天可能啥也不干,也可能进行拍照或show中的一种活动。每拍一次照,rating增加 a, 每参加一次show,rating减少 b。她现在想参加一次脱口秀。参加完脱口秀后的 l 天内, 她拍一次照rating增加 c,每参加一次show rating减少 d。要求参加脱口秀之前以及脱口秀之后 l 天内,她的rating是非负的。给出一些天数(从 0 开始)和当天的活动,求她应该选择哪一天参加脱口秀。如果有多解,输出其中最小的那个。
思路
就是模拟这个过程。
从 0 开始枚举在第 i 次活动之前参加脱口秀。用一个set维护脱口秀影响的时间rain个的值。set为空,说明脱口秀影响期间rating不变化,答案成立。由于set有序,第一个元素就是最小值。如果在这一天满足条件,则答案成立。
更多细节见代码
链接
http://codeforces.com/contest/887/problem/D
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, int> P;
const int maxn = 3e5 + 10;
int n, a, b, c, d, s, l;
int t[maxn], ty[maxn];
LL psuma[maxn], psumc[maxn];
set<P> se;
int solve(){
se.clear();
int R = 1;
LL add = 0;
t[0] = -1;
for(int i = 1; i <= n + 1; ++i){
if(psuma[i-1] < 0) return -1;
int lb = t[i-1] + 1, ub = lb + l;
int k = lower_bound(t+1, t+1+n, ub) - t;
while(R < k){
se.insert(P(psumc[R], R));
++R;
}
set<P>::iterator it = se.begin();
if(se.empty() || it->first + add >= 0) return lb;
se.erase(P(psumc[i], i));
add = psuma[i] - psumc[i];
}
return -1;
}
int main(){
scanf("%d %d %d %d %d %d %d", &n, &a, &b, &c, &d, &s, &l);
psuma[0] = psumc[0] = s;
for(int i = 1; i <= n; ++i){
scanf("%d %d", &t[i], &ty[i]);
if(ty[i]) psuma[i] = psuma[i-1] + a, psumc[i] = psumc[i-1] + c;
else psuma[i] = psuma[i-1] - b, psumc[i] = psumc[i-1] - d;
}
printf("%d\n", solve());
return 0;
}