题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

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

输出样例#1:

15

思路:这道题目我们可以考虑先记录每种电影上一次开播时间和下一次开播时间(即以下代码中的\(last\)数组和\(nxt\)数组),然后对于每种电影,我们可以先处理中它是否播放过对后面区间的影响情况,然后再对\(n\)个时间点分别考虑,我们可以枚举左端点,然后根据左端点电影的播放情况就可以确定它可以影响到的最右端点,然后不断更新,更新过程中记录最大值,最后那个最大值即为答案。

洛谷P3582(自己写的题解)

代码:

#include<cstdio>
#include<algorithm>
#include<cctype>
#define ll long long
#define maxn 1000007
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
int n,m,f[maxn],nxt[maxn],last[maxn],a[maxn];
ll ans;
inline int qread() { //快读,不解释……
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';
return num*f;
}
struct Tree {
ll maxx,lazy;
}tree[maxn<<2];
inline void pushdown(int rt) { //下放lazy标记。
if(tree[rt].lazy) {
tree[ls].lazy+=tree[rt].lazy;
tree[rs].lazy+=tree[rt].lazy;
tree[rs].maxx+=tree[rt].lazy;
tree[ls].maxx+=tree[rt].lazy;
tree[rt].lazy=0;
}
}
void modify(int rt,int l,int r,int L,int R,int val) { //区间修改,用于后面的更新。
if(L>r||R<l) return;
if(L<=l&&r<=R) {
tree[rt].lazy+=val;
tree[rt].maxx+=val;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
modify(ls,l,mid,L,R,val),modify(rs,mid+1,r,L,R,val);
tree[rt].maxx=max(tree[ls].maxx,tree[rs].maxx);
}
int main() {
n=qread(),m=qread();
for(int i=1;i<=n;++i) f[i]=qread();
for(int i=1;i<=m;++i) a[i]=qread();
for(int i=n;i>=1;--i) nxt[i]=last[f[i]],last[f[i]]=i; //处理出nxt和last数组。
for(int i=1;i<=m;++i) {
if(last[i]) { //如果这个电影已经播放过。
int zrj=nxt[last[i]];
if(zrj) modify(1,1,n,last[i],zrj-1,a[i]);
//如果这不是最后一次播放这个电影,那么可以影响到的最右端点是nxt[last[i]]-1,然后last[i]就是左端点,也是第一次看,所以在这个区间加上这个电影的价值。
else modify(1,1,n,last[i],n,a[i]); //如果是最后一次,那么它将一直影响到最后。
}
}
for(int i=1;i<=n;++i) {
ans=max(ans,tree[1].maxx); //每次更新一下最大值。
int zrj=nxt[i];
if(zrj) { //如果第二次播放。
modify(1,1,n,i,zrj-1,-a[f[i]]); //在这次和之后的一次的区间上价值减去这个电影的价值,因为相同电影看了价值为0。
if(nxt[zrj]) modify(1,1,n,zrj,nxt[zrj]-1,a[f[i]]); //第二次和第三次之间加上这个电影的价值(因为是以第二次为左端点,只看了一次)。
else modify(1,1,n,zrj,n,a[f[i]]); //不然就把第二次之后的加上这个价值。
}
else modify(1,1,n,i,n,-a[f[i]]); //没有第二次播放,就从当前时间开始一直到最后,减去这个价值。
}
printf("%lld\n",ans);
return 0;
}

洛谷P3582 [POI2015]KIN的更多相关文章

  1. BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze doły

    [题解] 手残写错调了好久QAQ...... 洛谷的数据似乎比较水.. n个正整数!!这很重要 这道题是个类似two pointer的思想,外加一个单调队列维护当前区间内长度为d的子序列中元素之和的最 ...

  2. 洛谷 P3586 [POI2015]LOG

    P3586 [POI2015]LOG 题目描述 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它 ...

  3. 洛谷P3588 - [POI2015]Pustynia

    Portal Description 给定一个长度为\(n(n\leq10^5)\)的正整数序列\(\{a_n\}\),每个数都在\([1,10^9]\)范围内,告诉你其中\(s\)个数,并给出\(m ...

  4. 洛谷 P3585 [POI2015]PIE

    P3585 [POI2015]PIE 题目描述 一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色.你有一个a*b的印章,有些格子是凸起(会沾上墨水)的.你需要判断能否用这个印章印出纸上 ...

  5. 洛谷P3588 [POI2015]PUS

    题面 sol:说了是线段树优化建图的模板... 就是把一整个区间的点连到一个点上,然后用那个点来连需要连一整个区间的点就可以了,就把边的条数优化成n*log(n)了 #include <queu ...

  6. 洛谷P3586 [POI2015]LOG(贪心 权值线段树)

    题意 题目链接 Sol 显然整个序列的形态对询问没什么影响 设权值\(>=s\)的有\(k\)个. 我们可以让这些数每次都被选择 那么剩下的数,假设值为\(a_i\)次,则可以\(a_i\)次被 ...

  7. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

  8. 洛谷P3585 [POI2015]PIE

    传送门 题目大意:有个n*m的格子图,要求'x'点要被染成黑色 有个a*b的印章,'x'是可以染色的印章上的点. 要求用印章去染色格子 (1)印章不可以旋转. (2)不能把墨水印到纸外面. (3)纸上 ...

  9. BZOJ 3747 洛谷 3582 [POI2015]Kinoman

    [题解] 扫描线+线段树. 我们记第i部电影上次出现的位置是$pre[i]$,我们从$1$到$n$扫描,每次区间$(pre[i],i]$加上第i部电影的贡献$w[f[i]]$,区间$[pre[pre[ ...

随机推荐

  1. windows下安装 postgresql

    1. 下载PostgreSQL的源代码.解压. 2. 在Windows平台下编译需要跳过一个权限的检测,否则在编译的时候可能会出现错误. 在\src\backend\main\main.c文件中将   ...

  2. C++中函数模版和普通函数的区别

    函数模版和同名普通函数在同一个作用域中,会优先调用那个函数? 函数模型在进行调用的时候会进行严格的类型匹配,而普通函数在调用的时候,会进行函数参数类型转换(前提是自动类型转换). 调用函数模版,本质是 ...

  3. Oracle中spool命令实现的两种方法比较

    ---恢复内容开始--- 要输出符合要求格式的数据文件只需在select时用字符连接来规范格式.比如有如下表 SQL>; select id,username,password from myu ...

  4. ACM学习历程—Rotate(HDU 2014 Anshan网赛)(几何)

    Problem Description Noting is more interesting than rotation! Your little sister likes to rotate thi ...

  5. HTML a标签如何设置margin属性(转)

    很多同学发现对DIV有效的许多CSS属性对<a>或<p>标签都无效,好比说 <div style="margin-top:5px;"></ ...

  6. get and set

    (function () { function Student(name, age, gender) { this._name = name; this._age = age; this._gende ...

  7. js基础之变量类型

    1.NAN(Not a number) 不是一个数字 自身:console.log(NaN==NaN)和console.log(NaN===NaN)返回值都是false; 其他函数,isNaN()可用 ...

  8. 四种生成和解析XML文档的方法介绍

    解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 1.DOM(Document Object Model) DOM是用与平台和语言无关的方式表示XML文档的官方 ...

  9. js---倒计时的自动跳转.html

    ============================================================================== 倒计时的自动跳转.html <!DO ...

  10. ss1

    首先,对系统来一次升级,以解决一些莫名其妙的依赖问题. sudo yum update 然后安装Python-pip. sudo yum -y install python-pip 注意,通过yum包 ...