BZOJ 3747 Kinoman

Posted on 2016-10-24 19:42  ziliuziliu  阅读(126)  评论(0编辑  收藏  举报

和HEOI采花类似。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000050
using namespace std;
int n,m,f[maxn],w[maxn],regis[maxn],nxt[maxn];
int root,tot=0,ls[maxn<<2],rs[maxn<<2],cnt[maxn];
long long lazy[maxn<<2],mx[maxn<<2],val[maxn],ans=0;
int read()
{
    int data=0;char ch;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9') 
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
void get_table()
{
    long long ret=0;
    for (int i=1;i<=n;i++)
    {
        cnt[f[i]]++;
        if (cnt[f[i]]==1) ret+=w[f[i]];
        else if (cnt[f[i]]==2) ret-=w[f[i]];
        val[i]=ret;
    }
    for (int i=n;i>=1;i--)
    {
        if (!regis[f[i]]) nxt[i]=n+1;
        else nxt[i]=regis[f[i]];
        regis[f[i]]=i;    
    }
}
void build(int &now,int left,int right)
{
    now=++tot;lazy[now]=0;
    if (left==right)
    {
        mx[now]=val[left];
        return;
    }
    int mid=left+right>>1;
    build(ls[now],left,mid);
    build(rs[now],mid+1,right);
    mx[now]=max(mx[ls[now]],mx[rs[now]]);
}
void pushdown(int now)
{
    if (lazy[now]==0) return;
    lazy[ls[now]]+=lazy[now];lazy[rs[now]]+=lazy[now];
    mx[ls[now]]+=lazy[now];mx[rs[now]]+=lazy[now];
    lazy[now]=0;
}
long long ask(int now,int left,int right,int l,int r)
{
    pushdown(now);
    if ((left==l) && (right==r)) return mx[now];
    int mid=left+right>>1;
    if (r<=mid) return ask(ls[now],left,mid,l,r);
    else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
    else return max(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+1,right,mid+1,r));
}
void modify(int now,int left,int right,int l,int r,int x)
{
    if (l>r) return;
    pushdown(now);
    if ((left==l) && (right==r))
    {
        lazy[now]+=x;mx[now]+=x;
        return;
    }
    int mid=left+right>>1;
    if (r<=mid) modify(ls[now],left,mid,l,r,x);
    else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x);
    else 
    {
        modify(ls[now],left,mid,l,mid,x);
        modify(rs[now],mid+1,right,mid+1,r,x);
    }
    mx[now]=max(mx[ls[now]],mx[rs[now]]);
}
int main()
{
    n=read();m=read();
    for (int i=1;i<=n;i++) f[i]=read();
    for (int i=1;i<=m;i++) w[i]=read();
    get_table();
    build(root,1,n);
    for (int i=1;i<=n;i++)
    {
        ans=max(ans,ask(root,1,n,i,n));
        modify(root,1,n,i,nxt[i]-1,-w[f[i]]);
        modify(root,1,n,nxt[i],nxt[nxt[i]]-1,w[f[i]]);
    }
    printf("%lld\n",ans);
    return 0;
}