类似湘潭邀请赛的那个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;
}

京公网安备 11010502036488号