bzoj 3747: [POI2015]Kinoman(线段树)

来源:互联网 发布:招聘java程序员 编辑:程序博客网 时间:2024/05/16 01:47

3747: [POI2015]Kinoman

Time Limit: 60 Sec  Memory Limit: 128 MB
Submit: 706  Solved: 290
[Submit][Status][Discuss]

Description

共有m部电影,编号为1~m,第i部电影的好看值为w[i]。
在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部。
你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影。如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值。所以你希望最大化观看且仅观看过一次的电影的好看值的总和。

Input

第一行两个整数n,m(1<=m<=n<=1000000)。
第二行包含n个整数f[1],f[2],…,f[n](1<=f[i]<=m)。
第三行包含m个整数w[1],w[2],…,w[m](1<=w[j]<=1000000)。

Output

输出观看且仅观看过一次的电影的好看值的总和的最大值。

Sample Input

9 4
2 3 1 1 4 1 2 4 1
5 3 6 6

Sample Output

15
样例解释:
观看第2,3,4,5,6,7天内放映的电影,其中看且仅看过一次的电影的编号为2,3,4。

HINT

Source

鸣谢Jcvb

[Submit][Status][Discuss]

HOME Back


题解:线段树。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define N 1000003#define LL long long using namespace std; LL delta[N*4],tr[N*4],n,m;LL v[N],col[N];int next[N],point[N],pos[N];void update(int now){tr[now]=max(tr[now<<1],tr[now<<1|1]);}void pushdown(int now,int l,int r){int mid=(l+r)/2;if (delta[now]) { tr[now<<1]+=delta[now]; tr[now<<1|1]+=delta[now]; delta[now<<1]+=delta[now]; delta[now<<1|1]+=delta[now]; delta[now]=0; }}void qjchange(int now,int l,int r,int ll,int rr,LL v){if (ll<=l&&r<=rr){delta[now]+=v;tr[now]+=v;return;}int mid=(l+r)/2;pushdown(now,l,r);if (ll<=mid) qjchange(now<<1,l,mid,ll,rr,v);if (rr>mid)  qjchange(now<<1|1,mid+1,r,ll,rr,v);update(now);}int main(){freopen("a.in","r",stdin);freopen("my.out","w",stdout);scanf("%lld%lld",&n,&m);for (int i=1;i<=n;i++) { scanf("%lld",&v[i]);  next[point[v[i]]]=i;  if (!point[v[i]])  pos[v[i]]=i;point[v[i]]=i; }for (int i=1;i<=m;i++) scanf("%lld",&col[i]);for (int i=1;i<=m;i++) if (next[pos[i]]&&pos[i]) qjchange(1,1,n,pos[i],next[pos[i]]-1,col[i]); else if (pos[i]) qjchange(1,1,n,pos[i],n,col[i]);LL ans=0;for (int i=1;i<=n;i++) { ans=max(ans,tr[1]);  if (next[i]) qjchange(1,1,n,i,next[i]-1,-col[v[i]]); else qjchange(1,1,n,i,n,-col[v[i]]); if (next[i]) { if (next[next[i]])  qjchange(1,1,n,next[i],next[next[i]]-1,col[v[i]]); else  qjchange(1,1,n,next[i],n,col[v[i]]);    } }printf("%lld\n",ans);}


0 0
原创粉丝点击