题解:P13507 [OOI 2024] Three Arrays

模拟赛搬的题,假了一万次,我也不知道咋搞过去的。

食用本题解时需要感性理解每个操作和定义的合理性,最好不要先去想这么搞的必要性。

我们可以对两个数分开考虑,由于两者顺序无影响。为方便这里将 \(L\)\(R\) 数组统一记作上界 \(x\)

定义一个取 \(\min\) 操作比另一个取 \(\min\) 操作强,当且仅当删去另一个操作后不会对最终答案产生影响。
分析可以发现,其充要条件是前者的上界加上两者之间的变化量(根据位置可能为负)小于等于后者的上界。
形式化的,就是当 \(x_i+pre_j-pre_i\le x_j\) 又记作 \(x_i-pre_i\le x_j-pre_j\) 时,我们认为 \(i\) 强于 \(j\)\(pre\) 数组为 \(D\) 数组的前缀和。
特别的,当\(x_i+pre_j-pre_i=x_j\) 时,我们仅在满足 \(i<j\) 时认为 \(i\) 强于 \(j\),方便排序。

同时,需要预先将 \(L\)\(R\) 数组里的每个值与可能最大值(无前缀操作情况)取 \(\min\),这样可以使得无操作为最弱操作。

那么贪心的想,对于一个操作序列,我们把不强于当前最强操作,且不在序列里的操作选过来一定是不劣的,因为这样不会使当前答案增加,同时还可能使另一个序列答案增大。

显然的,一个操作是最强的当且仅当比他强的都选了另一边,这一性质同时成立。

然后就会有一种做法是枚举一个序列的最强操作,将且仅将比它强的操作选到另一边,可以发现,这就是最强操作为当前操作时的答案最大值,然后将所有最强操作情况答案取 \(\max\) 就是最终答案。

具体维护的话我们可以将两个序列的操作分别从强到弱排序,然后对于其中一个序列的操作从前到后枚举最强操作(还有空操作情况),同时记录必须选到另一边的操作(就是前缀操作)中在另一边最强操作(初始为空操作),两者分别计算答案相加再取最大值即可。

#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
int x[N],L[N],R[N],y[N],numa[N],numb[N],ida[N],idb[N],n;
bool cmpa(int u,int v){
    if(L[u]-y[u]!=L[v]-y[v])return L[u]-y[u]<L[v]-y[v];
    return u<v;
}
bool cmpb(int u,int v){
    if(R[u]-y[u]!=R[v]-y[v])return R[u]-y[u]<R[v]-y[v];
    return u<v;
}
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&x[i]);
    for(int i=1;i<=n;i++)scanf("%lld",&L[i]);
    for(int i=1;i<=n;i++)scanf("%lld",&R[i]);
    scanf("%lld%lld",&L[0],&R[0]);
    for(int i=1;i<=n;i++)y[i]=y[i-1]+x[i];
    for(int i=1;i<=n;i++){
        L[i]=min(L[i],L[0]+y[i]);
        R[i]=min(R[i],R[0]+y[i]);
    }
    for(int i=1;i<=n;i++)numa[i]=numb[i]=i;
    sort(numa+1,numa+n+1,cmpa);
    sort(numb+1,numb+n+1,cmpb);
    for(int i=1;i<=n;i++){
        ida[numa[i]]=i;
        idb[numb[i]]=i;
    }
    int ans=0,now=n+1;
    for(int i=1;i<=n;i++){
        ans=max(ans,R[numb[now]]+y[n]-y[numb[now]]+y[n]-y[numa[i]]+L[numa[i]]);
        now=min(now,idb[numa[i]]);
    }
    ans=max(ans,R[numb[now]]+y[n]-y[numb[now]]+y[n]+L[0]);
    printf("%lld\n",ans);
    return 0;
}
posted @ 2025-09-28 17:08  Igunareo  阅读(21)  评论(0)    收藏  举报