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[]记录每个位置的电影的上一个位置。

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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define INF 1e9
  4. #define LL long long
  5. struct node
  6. {
  7. int left,right;
  8. LL tag,mx;
  9. }tree[];
  10. int f[],w[],last[],pre[];
  11. int read()
  12. {
  13. int s=,fh=;char ch=getchar();
  14. while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
  15. while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
  16. return s*fh;
  17. }
  18. void Build(int k,int l,int r)
  19. {
  20. tree[k].left=l;tree[k].right=r;tree[k].tag=;tree[k].mx=;
  21. if(l==r)return;
  22. int mid=(l+r)/;
  23. Build(k*,l,mid);Build(k*+,mid+,r);
  24. }
  25. void Pushup(int k)
  26. {
  27. tree[k].mx=max(tree[k*].mx,tree[k*+].mx);
  28. }
  29. void Pushdown(int k)
  30. {
  31. if(tree[k].tag!=)
  32. {
  33. tree[k*].tag+=tree[k].tag;
  34. tree[k*+].tag+=tree[k].tag;
  35. tree[k*].mx+=tree[k].tag;
  36. tree[k*+].mx+=tree[k].tag;
  37. tree[k].tag=;
  38. }
  39. }
  40. void Add(int k,int l,int r,int add)
  41. {
  42. if(l<=tree[k].left&&tree[k].right<=r)
  43. {
  44. tree[k].tag+=(LL)add;
  45. tree[k].mx+=(LL)add;
  46. return;
  47. }
  48. Pushdown(k);
  49. int mid=(tree[k].left+tree[k].right)/;
  50. if(r<=mid)Add(k*,l,r,add);
  51. else if(l>mid)Add(k*+,l,r,add);
  52. else {Add(k*,l,mid,add);Add(k*+,mid+,r,add);}
  53. Pushup(k);
  54. }
  55. int main()
  56. {
  57. int n,m,i;
  58. LL ans;
  59. n=read();m=read();
  60. for(i=;i<=n;i++)f[i]=read();
  61. for(i=;i<=m;i++)w[i]=read();
  62. memset(last,,sizeof(last));
  63. memset(pre,,sizeof(pre));
  64. for(i=;i<=n;i++)
  65. {
  66. last[i]=pre[f[i]];
  67. pre[f[i]]=i;
  68. }
  69. Build(,,n);
  70. ans=-INF;
  71. for(i=;i<=n;i++)
  72. {
  73. Add(,last[i]+,i,w[f[i]]);
  74. if(last[i]!=)
  75. {
  76. Add(,last[last[i]]+,last[i],-w[f[i]]);
  77. }
  78. ans=max(ans,tree[].mx);
  79. }
  80. printf("%lld",ans);
  81. return ;
  82. }

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. 不对称密钥密码体系之RSA

    公钥密码的特性: 1.加密和解密使用不同的钥匙 2.从一个钥匙推出另一个钥匙在计算上不可行 3.每个钥匙都可以做加密和解密 RSA算法: 1978年, MIT三位数学家 R.L.Rivest,A.Sh ...

  2. 手动通过Lucene判断该pom文件中jar是否存在,子依赖没判断

    package lucne.test; import java.io.File; import java.io.FileNotFoundException; import java.io.IOExce ...

  3. 比较全面的gdb调试命令

    from:http://blog.csdn.net/xiajun07061225/article/details/8960332 http://blog.csdn.net/cjfeii/article ...

  4. qwt6在Windows下Qt5的编译,安装,初步使用

    今晚把qwt的编译,安装,初级使用放上来,以便需要的人,能更快部署好编程环境,不至于每次都像我这样花很多时间. 注意:Qtcreater使用的是什么编译器编译出来的,就要用那个编译器来编译qwt. 我 ...

  5. 对C#泛型中的new()约束思考

    对于new()约束,大家可能有一个误解,以为使用了new约束之后,在创建对象时与非泛型的版本是一致的:<public class Tester<T> where T:new() {  ...

  6. float right 换行bug

    Bug产生原因:块里面有换行的元素. CSS: .left{float: left;width: 100px;background: #fff000;} .right{float: right;wid ...

  7. 求和函数 sum详解

    sum()的参数是一个list: >>> sum([1,2,3]) 6 >>> sum(range(1,3)) 3 还有一个比较有意思的用法 a = range(1 ...

  8. Sass 编译的几种方法

    常常有人会问,使用 Sass 进行开发,那么是不是直接通过“<link>”引用“.scss”或“.sass”文件呢? 那么这里告诉大家,在项目中还是引用“.css”文件,Sass 只不过是 ...

  9. yum使用详细

    1.使用YUM查找软件包 命令:yum search~ 2.列出所有可安装的软件包 命令:yum list 3.列出所有可更新的软件包 命令:yum list updates 4.列出所有已安装的软件 ...

  10. linux压缩与解压缩 tar命令

    #压缩tar -czvf ***.tar.gz  filetar -cjvf ***.tar.bz2 file#解压缩tar -xzvf ***.tar.gz filetar -xjvf ***.ta ...