标签:
从左到右枚举左端点,用线段树维护每个右端点的愉♂悦值
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define ll long long
#define N 1000006
using namespace std;
inline int read(){
int ret=0;char ch=getchar();
while (ch<‘0‘||ch>‘9‘) ch=getchar();
while (‘0‘<=ch&&ch<=‘9‘){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
}
int n;
struct STnode{
int l,r;
ll maxv;
ll tag;
};
struct SegmentTree{
STnode t[4*N];
void PushUp(int x){t[x].maxv=max(t[x<<1].maxv,t[x<<1^1].maxv);}
void PushDown(int x){
if (t[x].l==t[x].r) t[x].tag=0;
if (!t[x].tag) return;
t[x<<1].maxv+=t[x].tag;
t[x<<1].tag+=t[x].tag;
t[x<<1^1].maxv+=t[x].tag;
t[x<<1^1].tag+=t[x].tag;
t[x].tag=0;
}
void build(int x,int l,int r){
t[x].l=l;t[x].r=r;t[x].tag=0;
if (l==r){t[x].maxv=0;return;}
int mid=(l+r)/2;
build(x<<1,l,mid);
build(x<<1^1,mid+1,r);
PushUp(x);
}
void modify(int x,int l,int r,int delta){
PushDown(x);
if (l<=t[x].l&&t[x].r<=r){
t[x].maxv+=delta;
t[x].tag+=delta;
return;
}
int mid=(t[x].l+t[x].r)/2;
if (l<=mid) modify(x<<1,l,r,delta);
if (r>mid) modify(x<<1^1,l,r,delta);
PushUp(x);
}
ll getans(){return t[1].maxv;}
} st;
int a[N],next[N],film,value[N];
int now[N];
int main(){
n=read();film=read();
for (int i=1;i<=n;++i) a[i]=read();
for (int i=1;i<=film;now[i++]=n+1) value[i]=read();
for (int i=n;i;--i){
next[i]=now[a[i]];
now[a[i]]=i;
}
st.build(1,1,n);
for (int i=1;i<=film;++i)
st.modify(1,now[i],next[now[i]]-1,value[i]);
ll ans=0;
for (int i=1;i<=n;++i){
ans=max(ans,st.getans());
st.modify(1,i,next[i]-1,-value[a[i]]);
if (next[i]<=n)
st.modify(1,next[i],next[next[i]]-1,value[a[i]]);
}
printf("%lld\n",ans);
return 0;
}
标签:
原文地址:http://www.cnblogs.com/wangyurzee7/p/5147911.html