题目描述

一个长度为n的序列,每个数为1~m之一。求一段连续子序列,使得其中之出现过一次的数对应的价值之和最大。

输入

第一行两个整数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)。

输出

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

样例输入

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

样例输出

15


题解

线段树区间合并

考虑从左到右添加数的过程:选出的以该数为右端点的连续子序列中,该数的贡献为w[a[i]],该数上一个相同的数的贡献为-w[a[i]](因为选择了该数就会重复,需要把该数的贡献减掉),再前面相同的数的贡献为0。

于是可以使用线段树实现单点修改和查询最大连续子段和(实际上是1~i的最大包含右端点连续子段和,但是考虑到如果最大连续子段和不包含右端点,那么以前它的贡献不会更差,因此无需讨论以前的贡献)。

时间复杂度为$O(n\log n)$。由于空间原因,数组不能无脑开到4倍,需要开$3.5*10^6$可过。

#include <cstdio>
#include <algorithm>
#define N 1000010
#define M 3500010
using namespace std;
int pos[N] , last[N] , v[N] , w[N];
long long sum[M] , lv[M] , rv[M] , tv[M];
inline void pushup(int x)
{
int l = x << 1 , r = x << 1 | 1;
sum[x] = sum[l] + sum[r];
lv[x] = max(lv[l] , sum[l] + lv[r]);
rv[x] = max(rv[r] , sum[r] + rv[l]);
tv[x] = max(rv[l] + lv[r] , max(tv[l] , tv[r]));
}
void update(int p , int a , int l , int r , int x)
{
if(l == r)
{
sum[x] = a , lv[x] = rv[x] = tv[x] = max(a , 0);
return;
}
int mid = (l + r) >> 1;
if(p <= mid) update(p , a , l , mid , x << 1);
else update(p , a , mid + 1 , r , x << 1 | 1);
pushup(x);
}
int main()
{
int n , m , i;
long long ans = 0;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &v[i]);
for(i = 1 ; i <= m ; i ++ ) scanf("%d" , &w[i]);
for(i = 1 ; i <= n ; i ++ )
{
last[i] = pos[v[i]] , pos[v[i]] = i;
update(i , w[v[i]] , 1 , n , 1);
if(last[i])
{
update(last[i] , -w[v[i]] , 1 , n , 1);
if(last[last[i]]) update(last[last[i]] , 0 , 1 , n , 1);
}
ans = max(ans , tv[1]);
}
printf("%lld\n" , ans);
return 0;
}

【bzoj3747】[POI2015]Kinoman 线段树区间合并的更多相关文章

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

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

  2. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  3. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  4. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  5. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  6. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  7. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  8. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  9. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

随机推荐

  1. JS中的var、let、const

    1.var 在全局window中申明则为全局变量,是全局对象 window 的属性. var sum = 0 console.log(window.sum) console.log(sum); 在函数 ...

  2. react中实现原生enter/回车事件及antdesign组件实现方式

    先直接上核心代码: this.goToHomePage换成自己逻辑 自己写的时候直接把this.goToHmoPage()换成自己的逻辑就行了,还有注意一点的是: 需要传个空函数,不然会报错 在com ...

  3. 爬虫学习(十六)——jsonpath

    jsonpath介绍 jsonpath是一种信息抽取类库,是从json文档中抽取指定信息的工具,提供多种语言实现的版本 jsonpath对json来说,就相当于xpath对于xml jsonpath和 ...

  4. Java的按值传递和按引用传递解说

    在网上看到的一个帖子解释Java的按值传递和按引用传递,感觉挺全面,就转过来,以供以后学习参考: 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  5. pip更改国内源

    国内源: 阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/豆瓣(dou ...

  6. GNU 关闭 MMU 和 Icache 和 Dcache

    1. cp15 寄存器   disable Icache 和 Dcache . disable_MMU: MCR p15,0,r0,c7,c7,0 MRC p15,0,r0,c1,c0,0 bic r ...

  7. python——闰年的判断

    写一个程序,判断给定年份是否为闰年. 这样定义闰年的:能被4整除但不能被100整除,或者能被400整除都是闰年. while(1): year = input("请输入一个年份,让我判断一下 ...

  8. POJ:3045-Cow Acrobats

    Cow Acrobats Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6253 Accepted: 2345 Descript ...

  9. 20145202马超《Java程序设计》第十周学习总结

    一.网络编程 1.网络概述 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据 ...

  10. struts2官方 中文教程 系列五:处理表单

    先贴个本帖的地址,免得其它网站被爬去了struts2教程 官方系列五:处理表单  即 http://www.cnblogs.com/linghaoxinpian/p/6906298.html 下载本章 ...