BZOJ 3747 [POI2015]Kinoman

题目在这里呀!

题意:

m部电影,n天放映,第i天放映第f[i]部电影,第i部电影的好看值为w[i]。
一个区间[l,r],在第l天到第r天内,如果第i部电影只被看过一遍,那么就有w[i]的贡献,求最大贡献。

题解:

感觉是一道好题哦~(5月份没更过博啊终于打算写几篇了qwq)

从暴力入手吧,枚举左端点l,向右扫,每次cnt[f[i]]++,如果此时cnt[f[i]]=1,则加上贡献,如果cnt[f[i]]=2,则减去当前贡献,去最大值。

那么怎么去优化它呢。我们可以考虑当左端点从l移动到l+1的时候,改变的贡献。所以用tree[i]记录l到i这段区间内的贡献,放入线段树中求最大值,现在就是要考虑如何修改了,我们用nxt[i]记录从第i天往下下一个f[i]是第几天。
所以当左端点移动时,cnt[f[l]]–,那么tree[l+1…nxt[l]-1]-=w[f[l]],tree[nxt[l]…nxt[nxt[l]]-1]+=w[f[l]],在线段树上区间修改即可。
好像没什么要多注意的?(我打这道题还算挺顺利的吧

//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 1001000
using namespace std;
int n,m,f[N],w[N],nxt[N],fr[N];
long long ans;

struct Segment{
    long long tag,val;
}t[N+N+N+N+N];

inline void pushdown(int p,int l,int r)
{
    if(l==r) return;
    t[p+p].tag+=t[p].tag;t[p+p+1].tag+=t[p].tag;
    t[p+p].val+=t[p].tag;t[p+p+1].val+=t[p].tag;
    t[p].tag=0;
}

void modify(int p,int l,int r,int x,int y,int delta)
{
    if(t[p].tag) pushdown(p,l,r);
    if(x<=l && r<=y){
        t[p].tag=delta;t[p].val+=delta;
        return;
    }
    int mid=(l+r)>>1;
    if(y<=mid) modify(p+p,l,mid,x,y,delta);
    else if(x>mid) modify(p+p+1,mid+1,r,x,y,delta);
    else modify(p+p,l,mid,x,mid,delta),modify(p+p+1,mid+1,r,mid+1,y,delta);
    t[p].val=max(t[p+p].val,t[p+p+1].val);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&f[i]);
    for(int i=1;i<=m;i++) scanf("%d",&w[i]);
    for(int i=n;i;i--){
        nxt[i]=fr[f[i]];
        fr[f[i]]=i;
    }
    for(int i=1;i<=m;i++)
         if(fr[i]){
             if(!nxt[fr[i]]) modify(1,1,n,fr[i],n,w[i]);
             else modify(1,1,n,fr[i],nxt[fr[i]]-1,w[i]);
         }
    for(int l=1;l<=n;l++){
        ans=max(ans,t[1].val);
        if(nxt[l]){
            modify(1,1,n,l,nxt[l]-1,-w[f[l]]);     
            if(nxt[nxt[l]]) modify(1,1,n,nxt[l],nxt[nxt[l]]-1,w[f[l]]);
            else modify(1,1,n,nxt[l],n,w[f[l]]);
        }
        else modify(1,1,n,l,n,-w[f[l]]);
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leo_nasir/article/details/80381484