类似湘潭邀请赛的那个dp...
但是湘潭邀请赛的那个dp比这个难,假如赛前做了这个线段树估计那个dp可以秒...
惨...
code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2;
int c[N];
int ls[N],lss[N];
ll w[N];
struct SegTree{
    ll l,r,lz;
    ll mx;
}Tr[N<<3];
void pushup(int u)
{
    Tr[u].mx=max(Tr[u<<1].mx,Tr[u<<1|1].mx);
}

void pushdown(int u)
{
    if(Tr[u].lz)
    {
        Tr[u<<1].mx+=Tr[u].lz;
        Tr[u<<1|1].mx+=Tr[u].lz;
        Tr[u<<1].lz+=Tr[u].lz;
        Tr[u<<1|1].lz+=Tr[u].lz;
        Tr[u].lz=0;
    }
}

void add(int u,int l,int r,ll k)
{
    if(l>r)                     return;
    if(l>Tr[u].r||r<Tr[u].l)    return;
    if(l<=Tr[u].l&&Tr[u].r<=r)
    {
        Tr[u].lz+=k;
        Tr[u].mx+=k;
        return;
    }
    pushdown(u);
    add(u<<1,l,r,k);
    add(u<<1|1,l,r,k);
    pushup(u);
}

ll query(int u,int l,int r)
{
    if(l>r)                     return 0;
    if(l>Tr[u].r||r<Tr[u].l)    return 0;
    if(l<=Tr[u].l&&Tr[u].r<=r)  return Tr[u].mx;
    pushdown(u);
    return max(query(u<<1,l,r),query(u<<1|1,l,r));
}

void build(int u,int l,int r)
{
    Tr[u].l=l,Tr[u].r=r;
    Tr[u].mx=Tr[u].lz=0;
    if(l==r)    return;
    int mid=(l+r)>>1;
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);
}

void run()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        memset(ls,0,sizeof ls);
        memset(lss,0,sizeof lss);
        for(int i=1;i<=m;i++)
            scanf("%lld",&w[i]);
        build(1,1,n);
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            add(1,ls[c[i]]+1,i,w[c[i]]);
            add(1,lss[c[i]]+1,ls[c[i]],-w[c[i]]);
            ans=max(ans,query(1,1,i));
            lss[c[i]]=ls[c[i]];
            ls[c[i]]=i;
        }
        printf("%lld\n",ans);
    }
}

int main()
{
    int T=1;
    while(T--)
    {
        run();
    }
    return 0;
}