求助 0pts
查看原帖
求助 0pts
754021
fish_love_cat楼主2024/6/16 18:56

思路是求出每个点转向次数,然后从外向内操作,注意到对最外层的操作同时能影响内层,设 sumsum 记录已操作次数,JudgementJudgement 记录是否已被影响,ml 记录从左到右到当前第 ii 为的最小值,mrmr 记录从右到左。

不知道是不是思路假了,但是看提交记录过的点挺多的啊。

https://www.luogu.com.cn/record/162381374

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[200005],ml[200005],mr[200005],f[200005],sum,ans;
bool Judgement[200005];
signed main(){
    int n,m;
    cin>>n>>m;
    ml[0]=mr[n+1]=1e9;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)ml[i]=min(ml[i-1],a[i]);
    for(int i=n;i>=1;i--)mr[i]=min(mr[i+1],a[i]);
    for(int i=1;i<=m;i++){
        int l,r,k;
        cin>>r>>l>>k;
        f[l]=max(f[l],k-1),f[r]=max(f[r],k);
    }
    list<int> l;
    for(int i=1;i<=n;i++)
    if(f[i])l.push_back(i);
/*
    for(int i=1;i<=n;i++)cout<<a[i]<<' ';
    cout<<endl;
    for(int i=1;i<=n;i++)cout<<f[i]<<' ';
    cout<<endl;
    for(int i=1;i<=n;i++)cout<<ml[i]<<' ';
    cout<<endl;
    for(int i=1;i<=n;i++)cout<<mr[i]<<' ';
    cout<<endl;
    for(int i=1;i<=l.size();i++)cout<<l.front()<<' ',l.push_back(l.front()),l.pop_front();
    cout<<endl<<endl;
*/
    while(!l.empty()){
        while(!l.empty()&&sum>=f[l.front()]&&!Judgement[l.front()])l.pop_front();
        while(!l.empty()&&sum>=f[l.back()]&&!Judgement[l.back()])l.pop_back();
        if(l.empty())break;
/*
        cout<<sum<<endl;
        cout<<l.front()<<' '<<l.back()<<endl;
        cout<<f[l.front()]<<' '<<f[l.back()]<<endl;
*/
        if(l.size()>1){
            if(!Judgement[l.front()])f[l.front()]-=sum,Judgement[l.front()]=1;
            if(!Judgement[l.back()])f[l.back()]-=sum,Judgement[l.back()]=1;
            ans+=(ml[l.front()]*min(f[l.front()],f[l.back()])+mr[l.back()]*min(f[l.front()],f[l.back()]));
            sum+=min(f[l.front()],f[l.back()]);
            if(f[l.front()]>f[l.back()])f[l.front()]-=f[l.back()],l.pop_back();
            else if(f[l.front()]<f[l.back()])f[l.back()]-=f[l.front()],l.pop_front();
            else l.pop_front(),l.pop_back();
        }else{
            if(!Judgement[l.back()])f[l.back()]-=sum,Judgement[l.back()]=1;
            ans+=(mr[l.back()]*f[l.back()]);
            break;
        }
    }
    cout/*<<endl*/<<ans;
    return 0;
}
2024/6/16 18:56
加载中...