题解:P10607 物理实验 (hard)
简单题,有上一问的基础非常容易。
这里每个要条件需要达成最少
但是参考一下上一题:走到最后再往回。那这个是不是每次都走到最前面再往后呢?没错!我们开个结构体将条件按
前一个从前往后扫维护最前面的
记得开 long long,因为这个 WA 了好几次QAQ。
时间复杂度在排序
Code
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int M=2e5+10;
int n,m;
int a[M],mnh[M],mnq[M];
struct NODE{
int x,y,k,id;
}n1[M],n2[M];
bool cmpx(const NODE&A,const NODE&B){
if(A.x==B.x)return A.y<B.y;
return A.x<B.x;
}
bool cmpy(const NODE&A,const NODE&B){
if(A.y==B.y)return A.k>B.k;
return A.y<B.y;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d%d%d",&n1[i].x,&n1[i].y,&n1[i].k),n2[i]=n1[i],n1[i].id=n2[i].id=i;
sort(n1+1,n1+m+1,cmpx);
sort(n2+1,n2+m+1,cmpy);
mnh[n]=a[n];
for(int i=n-1;i>=1;i--)mnh[i]=min(mnh[i+1],a[i]);
mnq[1]=a[1];
for(int i=2;i<=n;i++)mnq[i]=min(mnq[i-1],a[i]);
int l=1,r=m,k=0;
LL ans=0;
while(r>=1){
int nr=n1[r].k-k,nl=n2[l].k-k;
int nk=min(nl,nr);
ans+=1ll*nk*mnh[n1[r].x]+1ll*nk*mnq[n2[l].y];
k+=nk;
while(n1[r].k<=k&&r>=1)r--;
while(n2[l].k<=k&&l<=m)l++;
}
ans-=mnq[n2[1].y];
cout<<ans<<endl;
return 0;
}