旅行规划(travel)
题目描述
OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 nnn 个最著名的经典连接起来,让游客可以通过火车从铁路起点( 111 号景点)出发,依次游览每个景区。为了更好的评价这条铁路,xkszltl 为每一个景区都赋予了一个美观度,而一条旅行路径的价值就是它所经过的景区的美观度之和。不过,随着天气与季节的变化,某些景点的美观度也会发生变化。
xkszltl 希望为每位旅客提供最佳的旅行指导,但是由于游客的时间有限,不一定能游览全部景区,然而他们也不希望旅途过于短暂,所以每个游客都希望能在某一个区间内的车站结束旅程,而 xkszltl 的任务就是为他们选择一个终点使得旅行线路的价值最大。可是当地的景点与前来观光的旅客实在是太多了,xkszltl 无法及时完成任务,于是找到了准备虐杀 NOI2019 的你,希望你能帮助他完成这个艰巨的任务。
输入格式
第一行给出一个整数 nnn,接下来一行给出 nnn 的景区的初始美观度。
第三行给出一个整数 mmm,接下来 mmm 行每行为一条指令:
1. 0 x y k1.~~~0~x~y~k1. 0 x y k:表示将 xxx 到 yyy 这段铁路边上的景区的美观度加上 kkk;
2. 1 x y2.~~~1~x~y2. 1 x y:表示有一名旅客想要在 xxx 到 yyy 这段(含 xxx 与 yyy )中的某一站下车,你需要告诉他最大的旅行价值。
对于 100%100\%100% 的数据,n,m≤100000n,m≤100000n,m≤100000
solution
要支持区间加一个一次函数,求最大值,线段树支持不了。
我们考虑用分块凸包。
一段区间加一次函数,凸包是不会变的。
这一点我当时没有想到,于是就想不出来。
加这一段一次函数的时候,每一条边的斜率都加了相同的数,也就是斜率大小关系不变。
那么凸包就不变了。
查询的话凸包上二分斜率找到分界点。单块的暴力查。
效率O(n^1.5*logn)
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
#define ll long long
#define inf 1e15
using namespace std;
int n,m,M,o;
ll ans,a[maxn];
struct no{ll x,y;};
struct node{
int ne,l,r,len,top;
ll p[],bj,bk;
no t[];
}s[];
void add_p(int id,int i,ll v){
s[id].ne=;
int pl=i-s[id].l+;
s[id].p[pl]+=v; }
void add(int id,ll v,ll k){
s[id].bj+=v;s[id].bk+=k;
}
ll cr(no a,no b){
return a.x*b.y-a.y*b.x;
}
void build(int id){
s[id].ne=;
for(int i=;i<=s[id].len;i++){
s[id].p[i]+=s[id].bj;
s[id].p[i]+=s[id].bk*i;
}
s[id].bj=s[id].bk=;int tp=;
for(int i=;i<=s[id].len;i++){
while(tp>&&cr(
(no){i-s[id].t[tp-].x,s[id].p[i]-s[id].t[tp-].y}
,(no){s[id].t[tp].x-s[id].t[tp-].x,s[id].t[tp].y-s[id].t[tp-].y}
)<)tp--;
s[id].t[++tp]=(no){i,s[id].p[i]};
}
s[id].top=tp;
}
double getk(no a,no b){
return (a.y-b.y)/(a.x-b.x);
}
void ask(int id){
if(s[id].ne)build(id);
int l=,r=s[id].top;
while(l+<r){
int mid=(l+r)>>;
if(mid==||mid==s[id].top)break;
double lk=getk(s[id].t[mid],s[id].t[mid-])+s[id].bk;
double rk=getk(s[id].t[mid+],s[id].t[mid])+s[id].bk;
if(rk>)l=mid;
else if(lk<)r=mid;
else {l=r=mid;break;}
}
ll Max=-inf;
for(int i=l-;i<=r+;i++){
if(i<||i>s[id].top)continue;
int c=s[id].t[i].x;
Max=max(Max,s[id].p[c]+s[id].bj+s[id].bk*c);
}
ans=max(ans,Max);
}
void ask_p(int id,int i){ if(s[id].ne)
build(id);
int pl=i-s[id].l+;
if(i<s[id].l||i>s[id].r)while();
ans=max(ans,s[id].p[pl]+s[id].bj+s[id].bk*pl);
}
int main()
{
cin>>n;o=sqrt(n);
for(int i=;i<=n;i++)scanf("%lld",&a[i]),a[i]+=a[i-];
int la=;
for(int i=;;i++){
s[i].l=max(la,),s[i].r=min(la+o-,n);
s[i].len=s[i].r-s[i].l+;M=i;
if(s[i].r==n)break;
la=la+o;
}s[M+].l=1e9;
for(int i=;i<=n;i++)add_p(i/o,i,a[i]);
cin>>m;
for(int ix=,op,x,y;ix<=m;ix++){
scanf("%d",&op);
if(op==){
scanf("%d%d",&x,&y);
int li=x/o,ri=y/o;ans=-inf;
for(int i=li+;i<ri;i++)ask(i);
for(;x<s[li+].l&&x<=y;x++)ask_p(x/o,x);
for(;y>s[ri-].r&&y>=x;y--)ask_p(y/o,y);
printf("%lld\n",ans);
}
else {ll v;
scanf("%d%d%lld",&x,&y,&v);int st=x,ed=y;
int li=x/o,ri=y/o;
for(int i=li+;i<ri;i++)add(i,(s[i].l-st)*v,v);
for(;x<s[li+].l&&x<=y;x++)add_p(x/o,x,(x-st+)*v);
for(;y>s[ri-].r&&y>=x;y--)add_p(y/o,y,(y-st+)*v);
for(int i=ri+;i<=M;i++)add(i,(ed-st+)*v,);
for(int i=ed+;i<s[ri+].l&&i<=n;i++)add_p(i/o,i,(ed-st+)*v);
}
}
return ;
}
旅行规划(travel)的更多相关文章
- BZOJ2388:旅行规划(travel)——分块凸包
题目 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路 ...
- BZOJ2388 : 旅行规划
考虑分块,每块维护两个标记$ts,td$. 那么对于块中一个位置$i$,它的实际值为$i\times td+ts+v_i$. 修改的时候,对于整块,直接打标记,对于零散的暴力修改,然后重构凸壳,时间复 ...
- BZOJ 2388: 旅行规划 [分块 凸包 等差数列]
传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...
- 2019.01.20 bzoj2388: 旅行规划(分块+凸包)
传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi)答案一定会在凸包上 ...
- BZOJ2388: 旅行规划(分块 凸包)
题意 题目链接 Sol 直接挂队爷的题解了 分块题好难调啊qwq #include<bits/stdc++.h> #define LL long long using namespace ...
- VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)
题意: 给出一个树,树上每一条边的边权为 1,求树上所有最长链的点集并. 细节: 可能存在多条最长链!最长链!最长链!重要的事情说三遍 分析: 方法round 1:暴力乱搞Q A Q,边权为正-> ...
- 「BZOJ2388」旅行规划
传送门 分块+凸包 求出前缀和数组s 对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列.r~n加上k*(r-l+1). 分块之后对每一块维护两个标记,一个记录它加的等差数 ...
- @bzoj - 2388@ 旅行规划
目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...
- BZOJ 2388--旅行规划(分块&单调栈&二分)
2388: 旅行规划 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 405 Solved: 118[Submit][Status][Discuss] ...
随机推荐
- mac上配置java jdk环境
访问Oracle官网 http://www.oracle.com,浏览到首页的底部菜单 ,然后按下图提示操作: 2.点击“JDK DOWNLOAD”按钮: 3.选择“Accept Lisence Ag ...
- MySQL创建民族表的SQL语句
MySQL创建民族表的SQL语句 CREATE TABLE `nation` ( `id` ) unsigned NOT NULL AUTO_INCREMENT, `nation` ) NOT NUL ...
- 微信小程序CheckBox选中事件
1.微信小程CheckBox选中问题 <checkbox-group bindchange="checkboxChange" data-index="{{index ...
- 第4章 HDFS操作
目录 4.1 命令行操作 4.2 Java API操作 4.2.1 创建Java工程 4.2.2 读取数据 4.2.3 创建目录 4.2.4 创建文件 4.2.5 删除文件 4.2.6 遍历文件和目录 ...
- C语言结构体篇 结构体
在描述一个物体的属性的时候,单一的变量类型是无法完全描述完全的.所以有了灵活的结构体变量. 结构体变量从意义上来讲是不同数据类型的组合,从内存上来讲是在一个空间内进行不同的大小划分. 1.1 结构体类 ...
- Postgres常用命令之增、删、改、查
增.删.改.查: postgres=# \password postgres 为postgres进行密码设置: postgres=# CREATE USER test WITH PASSWORD '1 ...
- git rebase -i
git rebase -i 作用: 合并提交 示例: 如图所示: 原因: 出现了两个第十一章的提交信息, 其实提交内容是一样的, 但是提交概述不一样. 这就让我很不爽. 我想把两次的概述信息合并为一个 ...
- linux上Kettle定时执行(转换的单步执行,job的单步执行,环境变量,kettle定时功能,效率问题等)转自(http://blog.csdn.net/feng19821209/article/details/5800960)
1,Kettle跨平台使用. 例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下: 1)进入到Kettle部署的路径 ...
- 十、mysql之索引原理与慢查询优化
mysql之索引原理与慢查询优化 一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还 ...
- 3,MongoDB之数据类型
一.MongoDB 之数据类型 首先我们要先了解一下MongoDB中有什么样的数据类型: Object ID :Documents 自生成的 _id String: 字符串,必须是utf-8 Boo ...