3747: [POI2015]Kinoman

Time Limit: 60 Sec  Memory Limit: 128 MB
Submit: 553  Solved: 222
[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

题解:

线段树。。。

用last[]记录每个位置的电影的上一个位置。

然后从头到尾依次遍历,每次把 (当前位置的电影的上一个位置,当前位置] 这个区间加上当前电影的好看值。然后把 (当前位置的电影的上上一个位置,当前位置的电影的上一个位置] 这个区间减去当前电影的好看值。每次求区间最大值即可。

这个用线段树维护即可。。。

 #include<bits/stdc++.h>
using namespace std;
#define INF 1e9
#define LL long long
struct node
{
int left,right;
LL tag,mx;
}tree[];
int f[],w[],last[],pre[];
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
void Build(int k,int l,int r)
{
tree[k].left=l;tree[k].right=r;tree[k].tag=;tree[k].mx=;
if(l==r)return;
int mid=(l+r)/;
Build(k*,l,mid);Build(k*+,mid+,r);
}
void Pushup(int k)
{
tree[k].mx=max(tree[k*].mx,tree[k*+].mx);
}
void Pushdown(int k)
{
if(tree[k].tag!=)
{
tree[k*].tag+=tree[k].tag;
tree[k*+].tag+=tree[k].tag;
tree[k*].mx+=tree[k].tag;
tree[k*+].mx+=tree[k].tag;
tree[k].tag=;
}
}
void Add(int k,int l,int r,int add)
{
if(l<=tree[k].left&&tree[k].right<=r)
{
tree[k].tag+=(LL)add;
tree[k].mx+=(LL)add;
return;
}
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)Add(k*,l,r,add);
else if(l>mid)Add(k*+,l,r,add);
else {Add(k*,l,mid,add);Add(k*+,mid+,r,add);}
Pushup(k);
}
int main()
{
int n,m,i;
LL ans;
n=read();m=read();
for(i=;i<=n;i++)f[i]=read();
for(i=;i<=m;i++)w[i]=read();
memset(last,,sizeof(last));
memset(pre,,sizeof(pre));
for(i=;i<=n;i++)
{
last[i]=pre[f[i]];
pre[f[i]]=i;
}
Build(,,n);
ans=-INF;
for(i=;i<=n;i++)
{
Add(,last[i]+,i,w[f[i]]);
if(last[i]!=)
{
Add(,last[last[i]]+,last[i],-w[f[i]]);
}
ans=max(ans,tree[].mx);
}
printf("%lld",ans);
return ;
}

Bzoj 3747: [POI2015]Kinoman 线段树的更多相关文章

  1. BZOJ 3747 POI2015 Kinoman 段树

    标题效果:有m点,每个点都有一个权值.现在我们有这个m为点的长度n该序列,寻求区间,它仅出现一次在正确的点区间内值和最大 想了很久,甚至神标题,奔说是水的问题--我醉了 枚举左点 对于每个请求留点右键 ...

  2. 3747: [POI2015]Kinoman|线段树

    枚举左区间线段树维护最大值 #include<algorithm> #include<iostream> #include<cstdlib> #include< ...

  3. BZOJ 3747: [POI2015]Kinoman 【线段树】

    Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...

  4. 【BZOJ3747】[POI2015]Kinoman 线段树

    [BZOJ3747][POI2015]Kinoman Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第 ...

  5. BZOJ 3747 POI2015 Kinoman

    因为上午没有准备够题目,结果发现写完这道题没题可写了QAQ 又因为这道题范围是100w,我写了发线段树,以为要T,上午就花了一个小时拼命卡常数 结果下午一交居然过了QAQ 我们考虑枚举L,求最大R使得 ...

  6. 【bzoj3747】[POI2015]Kinoman 线段树区间合并

    题目描述 一个长度为n的序列,每个数为1~m之一.求一段连续子序列,使得其中之出现过一次的数对应的价值之和最大. 输入 第一行两个整数n,m(1<=m<=n<=1000000). 第 ...

  7. 【bzoj3747】[POI2015]Kinoman - 线段树(经典)

    Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...

  8. BZOJ3747:[POI2015]Kinoman(线段树)

    Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...

  9. 【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)

    3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 830  Solved: 338 Description ...

随机推荐

  1. SQL Join 的三种类型

    1.Hash Match Join Hash运算(即散列算法) 和Hash表. Hash运算是一种编程技术,用来把数据转换为符号形式,使数据可以更容易更快速地被检索.例如,表中的一行数据,可以通过程序 ...

  2. HTML5的全局属性

    contentEditable:是否允许用户编辑元素中的内容.contentEditable有两个值,一个True 一个False. 例子: <ul contentEditable=" ...

  3. Python全栈开发-web框架之django

    一:web框架 什么是web框架? Web应用框架(Web application framework)是一种开发框架,用来支持动态网站.网络应用程序及网络服务的开发.这种框架有助于减轻网页开发时共通 ...

  4. [python][flask][flask-SQLAlchemy]关于flask-SQLAlchemy的初级使用教程

    鉴于网上关于flask-SQLAlchemy的实例使用教程参差不齐,于此写下工作学习过程中的使用过程,以便分享交流. 对于python关于flask有一定了解的高端玩家来说,请转至flask官方开发文 ...

  5. web2py相关-------------------------------(一)初遇

    在第一次换工作的时候,希望转行 做编程,就面试了很多家,很多人问我 懂不懂html 书写,我非常诚实的告诉他们不会. 当然那时我很天真的认为,只要自己愿意学习这些都不是问题,事实证明人的学习能力是很快 ...

  6. 坑爹的NSIS转义符:$ (在NSIS的MessageBox中写换行文字)

    最近的项目中,发现了NSIS一个比较坑的地方:$ 不但是变量常量的开头,还是一个转义字符. 大家有没有发现,NSIS写的脚本中,如果要让弹出消息框中的文字带换行功能,“\r\n” 是不是很不管用呢? ...

  7. ssh登录docker容器

    ssh登录docker容器1.启动一个docker容器# docker run -t -i ubuntu/ruby:v1 /bin/bash2.然后在容器里,安装openssh-server open ...

  8. Remove linked list elements | leetcode

    Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...

  9. 使用自定义《UIActivity》进行内容分享-b

    简介 这段时间有很多朋友都问我关于怎么去集成ShareSDK或者友盟社会化分享SDK的问题, 其实我想说, Apple一开始就提供了一个类, 供我们去使用分享了, 在iOS 6之后更加增强了这个类, ...

  10. python is == 的区别

    要点: is 判断是否是同一个对象.是通过id来判断的    == 是通过值来判断的    为了提高内存利用率对一些简单的对象,如一些数值较小的int对象,python采用重用对象内存的方法 例如指向 ...