题解
给你一组数,数量为n,有m组操作,每一组操作对某一范围的数进行-d
每一组操作都有严格的先后顺序,问:最先使这组数中有负数的操作,是哪一组(即标号最小的操作)
不存在输出0,存在输出-1,和该标号
二分答案
差分:区间加和和区间减数
前缀和:还原区间修改的结果
#include<iostream>
#include<vector>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 1000005
#define inf 2147483647
int a[maxn], b[maxn];
int l[maxn], r[maxn], d[maxn];
ll sum[maxn];
int n, m, ans;
bool check(int k)
{
for (int i = 1; i <= n; i++)b[i] = a[i] - a[i - 1];
for (int i = 1; i <= k; i++)
b[l[i]] -= d[i], b[r[i] + 1] += d[i];
for (int i = 1; i <= n; i++)
{
sum[i] = b[i] + sum[i - 1];
if (sum[i]<0)
{
ans = k;
return true;
}
}
return false;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &d[i], &l[i], &r[i]);
int l = 1, r = m;
while (l<r)
{
int mid = (l + r) / 2;
if (check(mid))r = mid;
else
l = mid + 1;
}
if (!ans)
printf("0");
else
printf("-1\n%d", ans);
return 0;
}