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。
 
 
=========================================华丽丽的分割线===============================================
没什么难的吧,直接枚举左端点,然后右端点用一个线段树维护出最大值。
每一次改变左端点的时候,总会有一些点的值改变,然后发现就是几个区间修改。
然后直接写就好辣。
时间复杂度O(nlogn),代码如下:
  1. #include <bits/stdc++.h>
  2. #define Maxn 1000007
  3. using namespace std;
  4. int read()
  5. {
  6. int x=,f=;char ch=getchar();
  7. while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
  8. while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  9. return x*f;
  10. }
  11. struct seg
  12. {
  13. int lx,rx;
  14. long long tag,mx;
  15. };
  16. int n,m;
  17. int f[Maxn],w[Maxn];
  18. int next[Maxn],last[Maxn];
  19. seg tree[Maxn*];
  20. long long ans=;
  21. void build(int node, int l, int r)
  22. {
  23. tree[node].lx=l,tree[node].rx=r;
  24. tree[node].tag=,tree[node].mx=;
  25. if (l==r) return;
  26. int mid=(l+r)/;
  27. build(node*,l,mid);
  28. build(node*+,mid+,r);
  29. }
  30. void pushdown(int node)
  31. {
  32. if (tree[node].tag==) return;
  33. tree[node*].tag+=tree[node].tag;
  34. tree[node*].mx+=tree[node].tag;
  35. tree[node*+].tag+=tree[node].tag;
  36. tree[node*+].mx+=tree[node].tag;
  37. tree[node].tag=;
  38. }
  39. void update(int node, int l, int r, long long del)
  40. {
  41. if (tree[node].rx<l) return;
  42. if (tree[node].lx>r) return;
  43. if (tree[node].lx>=l&&tree[node].rx<=r)
  44. {
  45. tree[node].tag+=del;
  46. tree[node].mx+=del;
  47. return;
  48. }
  49. pushdown(node);
  50. update(node*,l,r,del);
  51. update(node*+,l,r,del);
  52. tree[node].mx=max(tree[node*].mx,tree[node*+].mx);
  53. }
  54. int main()
  55. {
  56. n=read(),m=read();
  57. memset(f,,sizeof(f));
  58. for (int i=;i<=n;i++)
  59. f[i]=read();
  60. memset(w,,sizeof(w));
  61. for (int i=;i<=m;i++)
  62. w[i]=read();
  63. memset(last,,sizeof(last));
  64. for (int i=n;i;i--)
  65. {
  66. next[i]=last[f[i]];
  67. last[f[i]]=i;
  68. }
  69. build(,,n);
  70. for (int i=;i<=m;i++)
  71. if (last[i])
  72. {
  73. if (next[last[i]]>)
  74. update(,last[i],next[last[i]]-,w[i]);
  75. else update(,last[i],n,w[i]);
  76. }
  77. for (int i=;i<=n;i++)
  78. {
  79. ans=max(ans,tree[].mx);
  80. int pos=next[i];
  81. if (pos>)
  82. {
  83. update(,i,pos-,-w[f[i]]);
  84. if (next[pos]>)
  85. update(,pos,next[pos]-,w[f[i]]);
  86. else update(,pos,n,w[f[i]]);
  87. } else update(,i,n,-w[f[i]]);
  88. }
  89. printf("%lld\n",ans);
  90. return ;
  91. }

【数据结构】bzoj3747Kinoman的更多相关文章

  1. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  2. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  3. 深入浅出Redis-redis底层数据结构(上)

    1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...

  4. 算法与数据结构(十五) 归并排序(Swift 3.0版)

    上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...

  5. 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)

    本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...

  6. 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

    今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...

  7. 算法与数据结构(八) AOV网的关键路径

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

  8. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  9. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

随机推荐

  1. Spring+quartz cron表达式(cron手册官方)完美理解

    ------------------------------------- 15 17/1 14/3 * * ? 从每小时的17分15秒开始 每分钟的15秒执行一次14:17:15 ...14:59: ...

  2. 3,SQL语句及数据库优化

       1,统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的. 所以封装成复用方法,用标准模板来控制. select*from dual select*Fr ...

  3. c++ class as sort function

    // constructing sets #include <iostream> #include <set> #include <string.h> bool f ...

  4. 深挖 NGUI 基础 之UIRoot (一)

    当你开始使用NGUI的时候,简单的从项目视图 中一个”Control”预设体 拖拽到场景视图中,你将会发现 Hierarchy层次面板中会出现以下层次结构: 其中 UI Root作为根节点,是每个NG ...

  5. Python简要标准库(5)

    hashlib Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 基本的生成MD密匙的函数 import hashlib md5 = hashlib.md5() md5.up ...

  6. bzoj1367 可并堆

    题面 参考:<左偏树的特点及运用--黄河源> 我们将这个数列划为很多个互不相交的区间,每一段区间内的 \(b\) 是相等的,即 \(b[l[i]]=b[l[i]+1]=...=b[r[i] ...

  7. LeetCode 92 ——反转链表 II

    1. 题目 2. 解答 我们需要先找到第 m 个结点及其上一个结点,然后将从 m 到 n 的结点进行反转,最后依次将 m 到 n 反转后的结点和 n 之后的结点放入原链表中即可. 从前往后依次遍历 m ...

  8. JQuery Ajax执行过程AOP拦截

    JQuery Ajax过程AOP:用于在Ajax请求发送过程中执行必备操作,比如加载数据访问令牌. $.ajaxSetup({ type: "POST", error: funct ...

  9. Coursera: Internet History, Technology, and Security

    课程网址:https://www.coursera.org/learn/internet-history 学习笔记: Week 1: History - Dawn of Early Computing ...

  10. PTA实验报告(循环 数组 函数)

    一.循环PTA实验作业 题目一.7-2 求平方根序列前N项和 1.本题PTA提交列表 2.设计思路 本题调用了sqrt数学函数计算平方根,其次只用了一层循环,计算平方根之后使用循环累加计算总和sum. ...