这个题首先很容易想到枚举1-m,再一个一个加起来,判断一下(最直白的暴力)
于是又很容易想到用差分数组可以优化一下。
就像这样
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1000005;
int d[maxn],s[maxn],t[maxn],r[maxn];
int c[maxn];int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&r[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&d[i],&s[i],&t[i]);
}
for(int i=1;i<=m;i++)
{
c[s[i]]+=d[i];c[t[i]+1]-=d[i];
int sum=0;
for(int j=1;j<=n;j++)
{
sum+=c[j];if(sum>r[j])
{cout<<"-1"<<endl<<i<<endl;return 0;}
}
}
cout<<0<<endl;
return 0;
}
然而这样只有40分。。。
我们又发现外层循换i=1-m是满足单调性的
SO,可以二分一下x(x是指1-x都满足条件)
就很愉快的ac了
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1000005;
int d[maxn],s[maxn],t[maxn],r[maxn];
int c[maxn];int n,m;
int ok(int x)
{
memset(c,0,sizeof(c));
for(int i=1;i<=x;i++)
{
c[s[i]]+=d[i];c[t[i]+1]-=d[i];
}
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=c[i];if(sum>r[i]) return 0;
}
return 1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&r[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&d[i],&s[i],&t[i]);
}
int l=0,r=m;int ans=-1;
while(l<=r)
{
int mid=(l+r)/2;
if(ok(mid)) {ans=mid;l=mid+1;}
else r=mid-1;
}
//printf("%d",ans);
if(ans==m) {printf("%d\n",0);}
else {printf("-1\n%d",ans+1);}
return 0;
}