1. 程式人生 > >BZOJ P3747「POI2015」Kinoman【線段樹】

BZOJ P3747「POI2015」Kinoman【線段樹】

#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; }