题目描述

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)的更多相关文章

  1. BZOJ2388:旅行规划(travel)——分块凸包

    题目 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 $n$ 个最著名的经典连接起来,让游客可以通过火车从铁路 ...

  2. BZOJ2388 : 旅行规划

    考虑分块,每块维护两个标记$ts,td$. 那么对于块中一个位置$i$,它的实际值为$i\times td+ts+v_i$. 修改的时候,对于整块,直接打标记,对于零散的暴力修改,然后重构凸壳,时间复 ...

  3. BZOJ 2388: 旅行规划 [分块 凸包 等差数列]

    传送门 题意: 区间加和询问一段区间内整体前缀和的最大值 刚才还在想做完这道题做一道区间加等差数列结果发现这道就是.... 唯一的不同在于前缀和一段区间加上等差数列后,区间后面也要加上一个常数!!! ...

  4. 2019.01.20 bzoj2388: 旅行规划(分块+凸包)

    传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi​)答案一定会在凸包上 ...

  5. BZOJ2388: 旅行规划(分块 凸包)

    题意 题目链接 Sol 直接挂队爷的题解了 分块题好难调啊qwq #include<bits/stdc++.h> #define LL long long using namespace ...

  6. VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)

    题意: 给出一个树,树上每一条边的边权为 1,求树上所有最长链的点集并. 细节: 可能存在多条最长链!最长链!最长链!重要的事情说三遍 分析: 方法round 1:暴力乱搞Q A Q,边权为正-> ...

  7. 「BZOJ2388」旅行规划

    传送门 分块+凸包 求出前缀和数组s 对于l~r加上k,相当于s[l]~s[r]加上一个首项为k,公差为k的等差数列.r~n加上k*(r-l+1). 分块之后对每一块维护两个标记,一个记录它加的等差数 ...

  8. @bzoj - 2388@ 旅行规划

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...

  9. BZOJ 2388--旅行规划(分块&单调栈&二分)

    2388: 旅行规划 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 405  Solved: 118[Submit][Status][Discuss] ...

随机推荐

  1. mac上配置java jdk环境

    访问Oracle官网 http://www.oracle.com,浏览到首页的底部菜单 ,然后按下图提示操作: 2.点击“JDK DOWNLOAD”按钮: 3.选择“Accept Lisence Ag ...

  2. MySQL创建民族表的SQL语句

    MySQL创建民族表的SQL语句 CREATE TABLE `nation` ( `id` ) unsigned NOT NULL AUTO_INCREMENT, `nation` ) NOT NUL ...

  3. 微信小程序CheckBox选中事件

    1.微信小程CheckBox选中问题 <checkbox-group bindchange="checkboxChange" data-index="{{index ...

  4. 第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 遍历文件和目录 ...

  5. C语言结构体篇 结构体

    在描述一个物体的属性的时候,单一的变量类型是无法完全描述完全的.所以有了灵活的结构体变量. 结构体变量从意义上来讲是不同数据类型的组合,从内存上来讲是在一个空间内进行不同的大小划分. 1.1 结构体类 ...

  6. Postgres常用命令之增、删、改、查

    增.删.改.查: postgres=# \password postgres 为postgres进行密码设置: postgres=# CREATE USER test WITH PASSWORD '1 ...

  7. git rebase -i

    git rebase -i 作用: 合并提交 示例: 如图所示: 原因: 出现了两个第十一章的提交信息, 其实提交内容是一样的, 但是提交概述不一样. 这就让我很不爽. 我想把两次的概述信息合并为一个 ...

  8. linux上Kettle定时执行(转换的单步执行,job的单步执行,环境变量,kettle定时功能,效率问题等)转自(http://blog.csdn.net/feng19821209/article/details/5800960)

    1,Kettle跨平台使用.    例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下:    1)进入到Kettle部署的路径 ...

  9. 十、mysql之索引原理与慢查询优化

    mysql之索引原理与慢查询优化 一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还 ...

  10. 3,MongoDB之数据类型

    一.MongoDB 之数据类型 首先我们要先了解一下MongoDB中有什么样的数据类型: Object  ID :Documents 自生成的 _id String: 字符串,必须是utf-8 Boo ...