题目描述

FJ最近买了1个新仓库, 内含N 个挤奶机,1 到N 编号并排成一行。

挤奶机i 每天能产出M(i) 单位的奶。不幸的是, 机器装得太近以至于如果一台机器i 在某天被使用, 那与它相邻的两台机器那一天不能被使用

(当然, 两端点处的机器分别只有一个与之相邻的机器)。

FJ 可自由选择不同的机器在不同的日子工作。

FJ感兴趣于计算在D 天内他能产出奶的最大值。在每天开始时, 他有足够的时间维护一个选中的挤奶机i, 从而改变它从那天起的每日产奶量M(i)。

给出这些每日的修改,请告诉FJ他D 天中能产多少奶。

题意简述

给定 n 个点排成一排,每个点有一个点权,多次改变某个点的点权并将最大点独立集计入答案,输出最终的答案

思路

记 tree[root][0/1][0/1] 表示以 root 为根的线段树左右区间选/不选的答案

tree[root][0][1] = max(tree[root<<1][0][1]+tree[root<<1|1][0][1],tree[root<<1][0][0]+tree[root<<1|1][0][1],tree[root<<1][0][0]+tree[root<<1|1][1][1])

tree[root][1][0] = max(tree[root<<1][1][0]+tree[root<<1|1][1][0],tree[root<<1][1][1]+tree[root<<1|1][0][0],tree[root<<1][1][0]+tree[root<<1|1][0][0])

tree[root][0][0] = max(tree[root<<1][0][1]+tree[root<<1|1][0][0],tree[root<<1][0][0]+tree[root<<1|1][0][0],tree[root<<1][0][0]+tree[root<<1|1][1][0])

tree[root][1][1] = max(tree[root<<1][1][1]+tree[root<<1|1][0][1],tree[root<<1][1][0]+tree[root<<1|1][1][1],tree[root<<1][1][0]+tree[root<<1|1][0][1])

代码

/************************************************
*Author : lrj124
*Created Time : 2019.11.06.21:55
*Mail : 1584634848@qq.com
*Problem : luogu3097
************************************************/
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 40000 + 10;
int n,d,tree[maxn<<2][2][2];
long long ans;
inline void pushup(int root) {
tree[root][0][1] = max(max(
tree[root<<1][0][1]+tree[root<<1|1][0][1],
tree[root<<1][0][0]+tree[root<<1|1][0][1]),
tree[root<<1][0][0]+tree[root<<1|1][1][1]);
tree[root][1][0] = max(max(
tree[root<<1][1][0]+tree[root<<1|1][1][0],
tree[root<<1][1][1]+tree[root<<1|1][0][0]),
tree[root<<1][1][0]+tree[root<<1|1][0][0]);
tree[root][0][0] = max(max(
tree[root<<1][0][1]+tree[root<<1|1][0][0],
tree[root<<1][0][0]+tree[root<<1|1][0][0]),
tree[root<<1][0][0]+tree[root<<1|1][1][0]);
tree[root][1][1] = max(max(
tree[root<<1][1][1]+tree[root<<1|1][0][1],
tree[root<<1][1][0]+tree[root<<1|1][1][1]),
tree[root<<1][1][0]+tree[root<<1|1][0][1]);
}
inline void build(int l,int r,int root) {
if (l == r) {
scanf("%d",&tree[root][1][1]);
return;
}
int mid = l+r>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushup(root);
}
inline void update(int l,int r,int num,int x,int root) {
if (l > num || r < num) return;
if (l == r) {
tree[root][1][1] = x;
return;
}
int mid = l+r>>1;
update(l,mid,num,x,root<<1);
update(mid+1,r,num,x,root<<1|1);
pushup(root);
}
int main() {
// freopen("luogu3097.in","r",stdin);
// freopen("luogu3097.out","w",stdout);
scanf("%d%d",&n,&d);
build(1,n,1);
for (int i = 1,x,y;i <= d;i++) {
scanf("%d%d",&x,&y);
update(1,n,x,y,1);
ans += max(max(tree[1][0][1],tree[1][1][0]),max(tree[1][1][1],tree[1][0][0]));
}
printf("%lld",ans);
return 0;
}

最新文章

  1. AnguarJS测试的实施步骤整理
  2. ps让文字的颜色变成图片的颜色
  3. php-访问数据库
  4. 1. windows环境安装Node.js
  5. .NET破解之轻量万能自定义信息管理系统
  6. 如何使用java调用DLL运行C++(初篇)
  7. 《OD学HBase》20160821
  8. Hadoop集群运行JNI程序
  9. PLSQL Developer过期要注冊表
  10. LogMiner的使用
  11. 【原创】基于禅道的Bug管理操作规范
  12. WebSphere--连接管理器
  13. js小结
  14. iphone 开发h5 踩过的坑
  15. 學習Echart 2.2.7
  16. spring整合redis(jedis)
  17. 使用HttpClient消费ASP.NET Web API服务
  18. Linux 常用小命令
  19. Android学习之BitMap用法实例
  20. np.stack() 与 tf.stack() 的简单理解

热门文章

  1. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概览
  2. rpm -ivh vsftpd-3.0.2-22.el7.x86_64.rpm出现error: open of vsftpd-3.0.2-22.el7.x86_64.rpm failed: No such file or directory的解决方法
  3. Day06_商品分类(vuetify-nginx-cors)与品牌查询
  4. Python os.stat_float_times() 方法
  5. PHP strptime() 函数
  6. mysql安装和配置详解以及Navicat连接失败问题
  7. CF804D Expected diameter of a tree 树的直径 根号分治
  8. 6.10 省选模拟赛 小C的利是 高斯消元 矩阵行列式
  9. 使用nexus搭建maven私库
  10. Spring学习总结(7)-AOP