【传送门:BZOJ3747】


简要题意:

  共有m部电影,编号为1到m,第i部电影的好看值为w[i]。

  在n天之中(从1到n编号)每天会放映一部电影,第i天放映的是第f[i]部

  你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,…,r天内所有的电影

  如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值

  所以你希望最大化观看且仅观看过一次的电影的好看值的总和


题解:

  线段树

  next[i]表示与第i天播放同一部电影的下一天,如果没有则为n+1(待会解释)

  因为如果l,r之间有相同电影,那么这部电影则没有好看值,所以第i天的电影的好看值只贡献于第i天到第next[i]-1天(所以为什么上一步next[i]=n+1)

  然后枚举l,用线段树维护每一天的好看总值

  枚举时,先把l到next[l]-1减掉l位置电影的好看值,然后如果next[next[l]]!=0,就把next[l]到next[next[l]]-1加上减掉l位置电影的好看值,然后l++,然后求出l到n的最大值,然后维护整体最大值即可

  注意加long long


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long LL;
struct node
{int l,r,lc,rc;LL c,lazy;
}tr[2100000];int trlen;
void bt(int l,int r)
{int now=++trlen;tr[now].l=l;tr[now].r=r;tr[now].c=tr[now].lazy=0;tr[now].lc=tr[now].rc=-1;if(l<r){int mid=(l+r)/2;tr[now].lc=trlen+1;bt(l,mid);tr[now].rc=trlen+1;bt(mid+1,r);}
}
void update(int now)
{int lc=tr[now].lc,rc=tr[now].rc;if(lc!=-1){tr[lc].c+=tr[now].lazy;tr[lc].lazy+=tr[now].lazy;}if(rc!=-1){tr[rc].c+=tr[now].lazy;tr[rc].lazy+=tr[now].lazy;}tr[now].lazy=0;
}
void change(int now,int l,int r,LL c)
{if(tr[now].l==l&&tr[now].r==r){tr[now].c+=c;tr[now].lazy+=c;return ;}int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;if(tr[now].lazy!=0) update(now);if(r<=mid) change(lc,l,r,c);else if(l>mid) change(rc,l,r,c);else change(lc,l,mid,c),change(rc,mid+1,r,c);tr[now].c=max(tr[lc].c,tr[rc].c);
}
LL findc(int now,int l,int r)
{if(tr[now].l==l&&tr[now].r==r) return tr[now].c;int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;if(r<=mid) return findc(lc,l,r);else if(l>mid) return findc(rc,l,r);else return max(findc(lc,l,mid),findc(rc,mid+1,r));
}
int t[1100000],next[1100000];
int ft[1100000],f[1100000];
LL w[1100000];
int main()
{int n,m;scanf("%d%d",&n,&m);memset(t,0,sizeof(t));memset(next,0,sizeof(next));memset(ft,0,sizeof(ft));for(int i=1;i<=n;i++){scanf("%d",&f[i]);if(t[f[i]]==0) ft[f[i]]=i;next[t[f[i]]]=i;t[f[i]]=i;}for(int i=1;i<=n;i++) if(next[i]==0) next[i]=n+1;for(int i=1;i<=m;i++) scanf("%lld",&w[i]);trlen=0;bt(1,n);for(int i=1;i<=m;i++) if(ft[i]!=0) change(1,ft[i],next[ft[i]]-1,w[i]);LL ans=findc(1,1,n);int l=1;while(l<n){change(1,l,next[l]-1,-w[f[l]]);if(next[next[l]]!=0) change(1,next[l],next[next[l]]-1,w[f[l]]);l++;ans=max(findc(1,l,n),ans);}printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/Never-mind/p/8697180.html

BZOJ3747: [POI2015]Kinoman相关推荐

  1. bzoj3747 [POI2015]Kinoman

    线段树,记录next[i]下一部与当前电影一样的位置,然后枚举区间左端点i,询问线段树最大值后删除i到next[i-1]这段区间的观影值,且增加next[i]到next[next[i]]-1这段区间的 ...

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

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

  3. BZOJ 3747 POI2015 Kinoman 段树

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

  4. bzoj 3747: [POI2015]Kinoman

    (颓废扒题解2333) 给颜色的下一个出现位置记录一下,然后每次只有第一个颜色的出现位置和下一个出现位置之间会产生这种颜色的价值,所以用线段树维护一下区间. 那么现在就只需要把整个的数列从1-> ...

  5. [颓废史]蒟蒻的刷题记录

    QAQ蒟蒻一枚,其实我就是来提供水题库的. 以下记录从2016年开始. 1.1 1227: [SDOI2009]虔诚的墓主人 树状数组+离散化 3132: 上帝造题的七分钟 树状数组 二维区间加减+查 ...

  6. 【POI2015】KIN/Kinoman

    题目链接 传送门-洛谷 传送门-bzoj 思路 考虑枚举右端点.首先考虑应用前缀和,对于一个r,找一个最小的sum[l],把需要去掉的部分也放到sum[l]里.但这种做法是错的-.对于一个i,把他上一 ...

  7. [POI2015]CZA

    [POI2015]CZA p很小,讨论 p=0... p=1... p=2:n-1放左或者放右两种情况,剩下怎么放是固定的,模拟然后判断即可 p=3: 正着做要状压,类似放书和排座位那些题,考虑以某个 ...

  8. P3591 [POI2015]ODW(分块)

    P3591 [POI2015]ODW 给定一颗有nnn个节点的树,点有点权,给定一个长度为nnn的排列ppp,给定一个长度为n−1n - 1n−1的数组ccc, 我们会在树上进行n−1n - 1n−1 ...

  9. bzoj4380[POI2015]Myjnie dp

    [POI2015]Myjnie Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special Judge Submit: 368  Solved: 185 ...

最新文章

  1. 职称计算机考试题纲,2017年职称计算机考试大纲
  2. 关于HTML头二行文字的解释
  3. 十分简洁的手机浏览器 lydiabox
  4. jsp动作元素include学习
  5. 关于 WPF Loading初始界面的实现方式
  6. Flutter RichText 富文本标签样式 局部文字点击事件
  7. SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第二篇)
  8. 关于《ASP.NET MVC企业级实战》
  9. 最长公共前缀 python_python 实现求解字符串集的最长公共前缀方法
  10. java三年面试题(分布式篇)不定期更新
  11. 详解十三款运维监控工具
  12. oracle默认端口号是,sqlserver、mysql、oracle各自的默认端口号
  13. JavaWeb项目--【在线音乐播放器】onlineMusicPlayer
  14. 联想Y450电源管理无法调节屏幕亮度的解决办法
  15. Echarts 实现树状图的展示与编辑示例
  16. 云队友丨如何长久、持续且稳定的做一件事?
  17. 国防科技大学计算机考研资料汇总
  18. 如何用电脑模拟手机屏幕滑动 Total Control帮您实现
  19. app通过电商变现方式探讨
  20. 哔哩哔哩如何提取封面_如何提取封面

热门文章

  1. 26-Ubuntu-文件和目录命令-其他命令-管道
  2. 自动分号插入 ASI
  3. java 中的 Scanner
  4. C++相关:动态内存和智能指针
  5. codevs1127 接水问题
  6. 集群环境配置遇到的问题(随时更新)
  7. linux非阻塞的socket EAGAIN的错误处理【转】
  8. 能拯救你的人也只能是自己
  9. Android 小技巧
  10. 根据需要通过代码的方式加载js文件