开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
题目:我们需要处理接下来 n 天的借教室信息,其中第 i 天学校有ri 个教室可供租借。共有 m 份订单,每份订单用三个正整数描述,分别为 dj,sj,tj,表示某租借者需要从第sj 天到第tj 天租借教室(包括第 sj 天和第 tj 天),每天需要租借 dj个教室。
我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供 dj个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。
借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第sj天到第tj天中有至少一天剩余的教室数量不足dj个。
现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。
思路:第一种方法是线段树维护区间的最小值和实现区间加法,之后直接做就可以,但是这种做法我吸氧才能过;第二种做法是二分,二分到第几个订单会不满足条件,也就是二分答案,check里面用差分数组来统计判断
代码是线段树的
#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
//#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e9;
const double pi=acos(-1);
const int N=1e6+100;
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int ro[N];
struct seg{
int lazy,val;
}t[N<<2];
void pushup(int p){t[p].val=min(t[p<<1].val,t[p<<1|1].val);}
void build(int l,int r,int p){
t[p].val=t[p].lazy=0;
if(l==r){
t[p].val=ro[l];
return;
}
int m=l+r>>1;
build(l,m,p<<1);
build(m+1,r,p<<1|1);
pushup(p);
}
void pushdown(int p){
t[p<<1].lazy+=t[p].lazy;
t[p<<1|1].lazy+=t[p].lazy;
t[p<<1].val+=t[p].lazy;
t[p<<1|1].val+=t[p].lazy;
t[p].lazy=0;
}
void update(int L,int R,int l,int r,int p,int c){
if(l>r||l>R||r<L) return;
if(l>=L&&r<=R){
t[p].val+=c;
t[p].lazy+=c;
return;
}
int m=l+r>>1;
pushdown(p);
update(L,R,l,m,p<<1,c);
update(L,R,m+1,r,p<<1|1,c);
pushup(p);
}
int query(int L,int R,int l,int r,int p){
if(l>r||l>R||r<L) return inf;
if(l>=L&&r<=R) return t[p].val;
pushdown(p);
int minn=inf;
int m=l+r>>1;
minn=min({query(L,R,l,m,p<<1),query(L,R,m+1,r,p<<1|1),minn});
pushup(p);
return minn;
}
struct node{
int d,s,tj;
bool operator<(node a){return a.tj<tj;}
}st[N];
int n,m;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
build(1,n,1);
for(int i=1;i<=n;i++){
cin>>ro[i];
update(i,i,1,n,1,ro[i]);
}
for(int i=1;i<=m;i++) cin>>st[i].d>>st[i].s>>st[i].tj;
for(int i=1;i<=m;i++){
int minn=query(st[i].s,st[i].tj,1,n,1);
//cout<<i<<" "<<minn<<endl;
if(minn<st[i].d){cout<<"-1\n"<<i<<endl;return 0;}
update(st[i].s,st[i].tj,1,n,1,-st[i].d);
//cout<<i<<"ssss"<<endl;
}
cout<<0<<endl;
return 0;
}