分析:
其实是非常简单的贪心水题。。。
这题每个人有个上车时间,这会限制公交车从每个站点的出发时间。(注意,这里要把“到达时间”和“出发时间”区分开,不一定到达了就瞬间出发)。
首先,可以先算出到达每个站点的时间,这可以O(n)一遍算出来。(把到达时间,和从这里出发的最晚的一个人的时间取max,作为出发时间,然后再加上到达下一个点的路程,作为下一个点的到达时间,以此类推)
观察我们求值的方式,不难发现:如果某个点的到达时间,已经早于出发时间了,说明巴士是一定等了乘客的。这时候,无论在前面任何一个点加速,都无法影响到这个点后面的站点的到达时间。因为无论加多少,都会在这个站点停下来,等乘客。
所以在某个点加速,会影响到达时间的站点,就是从这里以后,到达的最近的一个:到达时间不超过出发时间的站点。
然后存下每个点加速1单位的贡献,用个优先队列就行了。更新靠线段树就可以了。(话说区间更改我居然没用懒标记。。。真的是昏了头了)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 1010
#define MAXM 10010
#define INF 0x3FFFFFFF
using namespace std;
typedef long long ll;
int n,m,k;
int d[MAXN],maxt[MAXN],las[MAXN],tx[MAXN];
int lp[MAXM],rp[MAXM],t[MAXM];
priority_queue<pair<int,int> > q;
int siz[MAXN];
int tree[MAXN*4],add[MAXN],tag[MAXN*4];
void build(int l,int r,int id){
if(l==r){
tree[id]=add[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,id*2);
build(mid+1,r,id*2+1);
tree[id]=min(tree[id*2],tree[id*2+1]);
}
void pushdown(int x){
tree[x*2]-=tag[x];
tree[x*2+1]-=tag[x];
tag[x*2]+=tag[x];
tag[x*2+1]+=tag[x];
tag[x]=0;
}
void change(int l,int r,int id,int pl,int pr){
if(l!=r)
pushdown(id);
if(l>=pl&&r<=pr){
tree[id]--;
tag[id]++;
return ;
}
int mid=(l+r)>>1;
if(pl<=mid)
change(l,mid,id*2,pl,pr);
if(pr>mid)
change(mid+1,r,id*2+1,pl,pr);
tree[id]=min(tree[id*2],tree[id*2+1]);
}
int que(int l,int r,int id,int pl,int pr){
if(l!=r)
pushdown(id);
if(l>=pl&&r<=pr){
return tree[id];
}
int res=INF;
int mid=(l+r)>>1;
if(pl<=mid)
res=min(res,que(l,mid,id*2,pl,pr));
if(pr>mid)
res=min(res,que(mid+1,r,id*2+1,pl,pr));
return res;
}
int update(int x){
int res=0;
while(las[x]!=x&&que(1,n,1,x,las[x]-1)==0){
res+=siz[las[x]+1];
las[x]--;
}
return res;
}
int main(){
SF("%d%d%d",&n,&m,&k);
for(int i=1;i<n;i++)
SF("%d",&d[i]);
for(int i=1;i<=m;i++){
SF("%d%d%d",&t[i],&lp[i],&rp[i]);
siz[rp[i]]++;
maxt[lp[i]]=max(maxt[lp[i]],t[i]);
}
int tims=0;
for(int i=1;i<=n;i++){
tx[i]=tims;
tims=max(tims,maxt[i]);
tims+=d[i];
add[i]=max(0,tims-maxt[i+1]);
}
ll ans=0;
for(int i=1;i<=m;i++)
ans+=tx[rp[i]]-t[i];
for(int i=1;i<=n;i++){
int res=0;
for(int j=i;j<=n;j++){
las[i]=j;
res+=siz[j+1];
if(add[j]==0)
break;
}
q.push(make_pair(res,i));
}
build(1,n,1);
while(k--&&!q.empty()){
pair<int,int> now=q.top();
q.pop();
int x=now.second;
int cnt=0;
for(int i=x;;i++){
cnt+=siz[i+1];
if(que(1,n,1,i,i)==0)
break;
}
if(d[x]==0){
k++;
continue;
}
if(now.first==0)
break;
if(las[x]!=x&&que(1,n,1,x,las[x]-1)==0){
now.first-=update(x);
q.push(now);
k++;
continue;
}
d[x]--;
ans-=now.first;
if(las[x]>x)
change(1,n,1,x,las[x]-1);
q.push(now);
}
PF("%lld",ans);
}