这就是个题面
两种做法啊,二分和线段树
一.二分+前缀和:
从第一天到第n天,一天一天地算,然后二分找有没有不符合的,虽然很暴力,但是可以做啊QAQ
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000000+10;
int n,m;
int rr[maxn],cha[maxn],d[maxn],t[maxn],s[maxn];
bool check(int x)
{
//printf("*%d\n",x);
memset(cha,0,sizeof(cha));
for(int i=1;i<=x;++i)
{
cha[s[i]]+=d[i];
cha[t[i]+1]-=d[i];
}
int sum=0;
for(int i=1;i<=n;++i)
{
sum+=cha[i];
if(sum>rr[i]) return false;
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&rr[i]);
for(int i=1;i<=m;++i) scanf("%d%d%d",&d[i],&s[i],&t[i]);
int l=1,r=m;
while(l+1<r)
{
int mid=(l+r)>>1;
if(check(mid)) l=mid;
else r=mid;
}
int ans;
if(!check(l)) ans=l;
else ans=r;
if(r==m&&check(r)) printf("0");
else
{
printf("-1\n");
printf("%d",ans);
}
return 0;
}
二.线段树
维护区间最小值,每次修改区间,查询是否有最小值小于零
一开始TLE,发现是询问最小值是,不用再写一个ask函数来询问刚刚修改的区间的最小值,而是直接O(1)询问区间1~n的最小值就可以了2333(感觉自己好智障)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e6+10,inf=0xfffffff;
int n,m,ans;
int rr[maxn];
struct hh
{
int l,r;
int minn;
int lazy;
}tree[maxn<<2];
void spread(int i)
{
int &x=tree[i].lazy;
if(x)
{
tree[i<<1].minn+=x;
tree[i<<1|1].minn+=x;
tree[i<<1].lazy+=x;
tree[i<<1|1].lazy+=x;
x=0;
}
}
void add(int l,int r,int x,int i)
{
int lx=tree[i].l,rx=tree[i].r;
if(lx>=l&&rx<=r)
{
tree[i].lazy-=x;
tree[i].minn-=x;
return;
}
spread(i);
int mid=(lx+rx)>>1;
if(l<=mid) add(l,r,x,i<<1);
if(r>mid) add(l,r,x,i<<1|1);
tree[i].minn=min(tree[i<<1].minn,tree[i<<1|1].minn);
}
void build(int l,int r,int i)
{
tree[i].l=l;
tree[i].r=r;
if(l==r)
{
tree[i].minn=rr[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
tree[i].minn=min(tree[i<<1].minn,tree[i<<1|1].minn);
}
int main()
{
memset(tree,0,sizeof(tree));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&rr[i]);
build(1,n,1);
for(int i=1;i<=m;++i)
{
int d,s,t;
scanf("%d%d%d",&d,&s,&t);
add(s,t,d,1);
if(tree[1].minn<0)
{
ans=i;
break;
}
}
if(ans) printf("-1\n");
printf("%d",ans);
return 0;
}