BZOJ P3747「POI2015」Kinoman【線段樹】
阿新 • • 發佈:2018-12-09
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define repd(i,x,y) for(int i=(x);i>=(y);i--)
using namespace std;
const int N=1 e6+5;
int n,m;
int f[N],w[N],last[N],nxt[N];
ll ans,mx[N<<2],lazy[N<<2];
#define lson (p<<1)
#define rson (p<<1|1)
#define mid (l+r>>1)
char buf[1<<20],*p1,*p2;
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
inline int read () {
int x=0;char ch=gc;bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=gc;}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}
return f?-x:x;
}
void pushdown(int p) {
mx[lson]+=lazy[p];
mx[rson]+=lazy[p];
lazy[lson]+=lazy[p];
lazy[rson]+=lazy[p];lazy[p]=0 ;
}
void update(int p,int l,int r,int x,int y,ll z) {
if(r<x||y<l) return ;
if(x<=l&&r<=y) {
mx[p]+=z;
lazy[p]+=z;return ;
}
if(lazy[p]) pushdown(p);
update(lson,l,mid,x,y,z);
update(rson,mid+1,r,x,y,z);mx[p]=max(mx[lson],mx[rson]);
}
int main() {
n=read(),m=read();
rep(i,1,n) f[i]=read();
rep(i,1,m) w[i]=read();
repd(i,n,1) nxt[i]=last[f[i]],last[f[i]]=i;
rep(i,1,m) if(last[i]) {
if(!nxt[last[i]]) update(1,1,n,last[i],n,w[i]);
else update(1,1,n,last[i],nxt[last[i]]-1,w[i]);
}
rep(i,1,n) {
ans=max(ans,mx[1]);
if(nxt[i]) {
update(1,1,n,i,nxt[i]-1,-w[f[i]]);
if(nxt[nxt[i]]) update(1,1,n,nxt[i],nxt[nxt[i]]-1,w[f[i]]);
else update(1,1,n,nxt[i],n,w[f[i]]);
} else update(1,1,n,i,n,-w[f[i]]);
}
printf("%lld\n",ans);
return 0;
}