bzoj4094 && luogu3097 最优挤奶
题目大意:
给定n个点排成一排,每个点有一个点权,有m次修改,每次改变某个点的点权并将最大点独立集计入答案,输出最终的答案
其中\(n\le 40000\ , \ m\le 50000\)
QWQ说实话,一开始看这个题,没啥思路呀
后来看了题解才知道是线段树
我们考虑对一个区间,我们只需要关心左右节点是否取,就可以从小的区间更新大区间。
从而实现线段树的区间合并了
QWQ我们定义
\(f[i].both\)表示左右边界都取
\(f[i].left\)表示只取左边界
\(f[i].right\)表示只取右边界
\(f[i].neither\)表示左右边界都不取
对于每种情况,我们分开讨论
首先定义\(l=2*root,r=2*root+1\)
对于\(f[root].both\)
\(f[root].both=max(f[l].left+max(f[r].both,f[r].right),f[l].both+f[r].right);\)
也就是如果左边只取左,右边可以都取或者只取右
如果左边都取,那么右边只能取右了(因为中间的左右区间的交界处也是不能同时取到的)
对于\(f[root].right,f[root].left\)
\(f[root].left=max(f[l].left+max(f[r].neither,f[r].left),f[l].both+f[r].neither);\)
\(f[root].right=max(f[l].neither+max(f[r].right,f[r].both),f[l].right+f[r].right);\)
同样的方法,处理一下
而对于\(f[root].neither\)
\(f[root].neither=max(max(f[l].neither+f[r].neither,f[l].right+f[r].neither),f[r].left+f[l].neither)\)
然后考虑更新的部分话
将一个点权修改也就是重新更新那个节点的\(f[root].both\),然后将其他的清零。
最后更新就行
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 40010;
struct Node{
int left,right,both,neither;
};
Node f[4*maxn];
int n,a[maxn];
int m;
long long ans;
void up(int root)
{
int l = 2*root,r=2*root+1;
f[root].both=max(f[l].left+max(f[r].both,f[r].right),f[l].both+f[r].right);
f[root].left=max(f[l].left+max(f[r].neither,f[r].left),f[l].both+f[r].neither);
f[root].right=max(f[l].neither+max(f[r].right,f[r].both),f[l].right+f[r].right);
f[root].neither=max(max(f[l].neither+f[r].neither,f[l].right+f[r].neither),f[r].left+f[l].neither);
}
void build(int root,int l,int r)
{
if (l==r)
{
f[root].left=f[root].right=f[root].neither=0;
f[root].both=a[l];
return;
}
int mid = (l+r) >> 1;
build(2*root,l,mid);
build(2*root+1,mid+1,r);
up(root);
}
void update(int root,int l,int r,int x,int p)
{
if (l==r)
{
f[root].left=f[root].right=f[root].neither=0;
f[root].both=p;
return;
}
int mid =(l+r) >> 1;
if (x<=mid) update(2*root,l,mid,x,p);
if (x>mid) update(2*root+1,mid+1,r,x,p);
up(root);
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for (int i=1;i<=m;i++)
{
int day,x;
day=read(),x=read();
update(1,1,n,day,x);
long long tmp=max(f[1].left,max(f[1].right,max(f[1].both,f[1].neither)));
ans+=tmp;
}
cout<<ans<<endl;
return 0;
}
bzoj4094 && luogu3097 最优挤奶的更多相关文章
- P3097 [USACO13DEC]最优挤奶Optimal Milking
P3097 [USACO13DEC]最优挤奶Optimal Milking 题意简述:给定n个点排成一排,每个点有一个点权,多次改变某个点的点权并将最大点独立集计入答案,输出最终的答案 感谢@zht4 ...
- 洛谷P3097 - [USACO13DEC]最优挤奶Optimal Milking
Portal Description 给出一个\(n(n\leq4\times10^4)\)个数的数列\(\{a_n\}(a_i\geq1)\).一个数列的最大贡献定义为其中若干个不相邻的数的和的最大 ...
- [P3097] [USACO13DEC] [BZOJ4094] 最优挤奶Optimal Milking 解题报告(线段树+DP)
题目链接:https://www.luogu.org/problemnew/show/P3097#sub 题目描述 Farmer John has recently purchased a new b ...
- P3097 [USACO13DEC]最优挤奶(线段树优化dp)
盲猜dp系列... 题意:给定序列,选了i就不能选与i相邻的两个,求最大值,带修改 蒟蒻在考场上10min打完以为只有两种情况的错解...居然能骗一点分... 先讲下当时的思路吧. f[i][0/1] ...
- 【USACO13DEC】 最优挤奶 - 线段树
题目描述 FJ最近买了1个新仓库, 内含N 个挤奶机,1 到N 编号并排成一行. 挤奶机i 每天能产出M(i) 单位的奶.不幸的是, 机器装得太近以至于如果一台机器i 在某天被使用, 那与它相邻的两台 ...
- poj 2112 最优挤奶方案
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 16550 Accepted: 5945 ...
- dp的林林总总(持续更新,dp骚气解法等等)
写在前面: 本人dp较弱,所以总结了一些坑点,转化思路以供复习使用,勿喷,甚至一些不是dp的题(贪心等等)也会放在这. 每个点后面会有我自己的题解,如果没有链接,向下找第一个链接,可能会有多题. 1. ...
- 题解 最优的挤奶方案(Optimal Milking)
最优的挤奶方案(Optimal Milking) 时间限制: 1 Sec 内存限制: 128 MB 题目描述 农场主 John 将他的 K(1≤K≤30)个挤奶器运到牧场,在那里有 C(1≤C≤20 ...
- 【BZOJ4094】[Usaco2013 Dec]Optimal Milking 线段树
[BZOJ4094][Usaco2013 Dec]Optimal Milking Description Farmer John最近购买了N(1 <= N <= 40000)台挤奶机,编号 ...
随机推荐
- 已知三角形ABC为锐角三角形,求 sinA + sinB·sin(C/2) 的最大值。
已知三角形ABC为锐角三角形,求 sinA + sinBsin(C/2) 的最大值. 解:Δ := sinA + sinB·sin(C/2) = sin(B+C) + sinB·sin(C/2) = ...
- 电子设备的使用方法-第5版(佳明智能腕表小米手机联想轻薄笔记本群晖存储)我的腾讯QQ电子邮箱地址是 595076941@qq.com - 2021年9月5日
电子设备的使用方法-第5版 (佳明智能腕表小米手机联想轻薄笔记本群晖存储) 2021年9月5日 我的腾讯QQ电子邮箱地址是 595076941@qq.com 前言 大家好,我叫徐晓亮,今天我 ...
- vue 接入 vod-js-sdk-v6.js 完成视频上传
东西有点多,耐心看完.按照操作一步一步来,绝对能成功 首先:npm 引入 npm install vod-js-sdk-v6 mian.js 全局引入 //腾讯云点播 import TcVod f ...
- 【CSS】按钮
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C# 爬虫框架实现 流程_各个类开发
目录链接:C# 爬虫框架实现 概述 对比通用爬虫结构,我将自己写的爬虫分为五个类实现: Spider主类:负责设置爬虫的各项属性 Scheduler类:负责提供URL到下载类,接收URL并做去重 Do ...
- QT开发实战一:图片显示
测试平台 宿主机平台:Ubuntu 12.04.4 LTS 目标机:Easy-ARM IMX283 目标机内核:Linux 2.6.35.3 QT版本:Qt-4.7.3 Tslib版本:tslib-1 ...
- 用python的pandas读取excel文件中的数据
一.读取Excel文件 使用pandas的read_excel()方法,可通过文件路径直接读取.注意到,在一个excel文件中有多个sheet,因此,对excel文件的读取实际上是读取指定文件.并 ...
- Marvell 88SE9215 AHCI驱动笔记
禁止转载!禁止转载!禁止转载! 一.Marvell 88SE9215.AHCI与SATA简介 1.Marvell 88SE9215 1)概述 88SE9215是一个四端口,兼容3 Gbps和6 Gbp ...
- 求1+2+…+n
求 1+2+...+n ,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 示例 1: 输入: n = 3 输出: 6 示例 2: ...
- 洛谷P1603——斯诺登的密码(字符串处理)
https://www.luogu.org/problem/show?pid=1603#sub 题目描述 2013年X月X日,俄罗斯办理了斯诺登的护照,于是他混迹于一架开往委内瑞拉的飞机.但是,这件事 ...