题解:P14567 【MX-S12-T2】区间
确定性的线性做法。
记
由于
所以对于每个左端点
扔掉区间是容易线性的,考虑怎么给
#include <bits/stdc++.h>
#define ll long long
using namespace std;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<20,stdin),S==T)?EOF:*S++)
char B[1<<20],*S=B,*T=B;
inline int read(){
int x=0,c=getchar();
while(c<48) c=getchar();
while(c>47) x=(x*10)+(c^48),c=getchar();
return x;
}
int n,c[1000005],v[1000005],f[1000005],r[1000005],s[1000005],stk[1000005],top,lst[1000005],pre[1000005],fs[1000005],ls[1000005];
int main(){
n=read();
for(int i=1;i<=n;i++) c[i]=read(),fs[c[i]]=(fs[c[i]]?fs[c[i]]:i),ls[c[i]]=i;
for(int i=1;i<=n;i++) v[i]=read();
for(int i=1;i<=n;i++) f[i]=read();
lst[0]=n+1;
for(int i=n,s=0;i;i--){
s+=(ls[c[i]]==i)-(fs[c[i]]==i),stk[++top]=i;
while(top&&fs[c[stk[top]]]>=i) top--;
if(lst[s]&&(!top||lst[s]<=stk[top])) r[i]=lst[s]-1;
lst[s]=i,pre[r[i]]=i;
}
for(int i=2;i<=n;i++) pre[i]=max(pre[i-1],pre[i]);
ll ans=1e18;
for(int i=1;i<=n;i++)
if(r[i]&&pre[r[i]]==i){
ll res=0;
for(int j=i;j<=r[i];j++) res+=v[j]*f[j-i+1];
ans=min(ans,res);
}
cout<<ans<<'\n';
return 0;
}