题目描述

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. Q&A - Apache、Nginx与Tomcat的区别?

    一.     定义: 1.     Apache Apache HTTP服务器是一个模块化的服务器,可以运行在几乎所有广泛使用的计算机平台上.其属于应用服务器.Apache支持支持模块多,性能稳定,A ...

  2. MySql开启GTID和多线程复制功能

    1.修改参数 master: gtid_mode = ON                        --开启gtid这个必须打开 enforce-gtid-consistency = ON    ...

  3. laravel cache get 是如何调用的?

    本文使用版本为laravel5.5 cache get public function cache() { $c=\Cache::get('app'); if(!$c) { \Cache::put(' ...

  4. vim编辑器使用习惯问题

    Ubuntu中vi在编辑状态下方向键不能用,一按方向键盘就出ABCD,想插入个字母还非常麻烦,还有回格键不能删除等我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full ...

  5. 基于THINKPHP+layui+Ajax无刷新实现图片上传预览

    <fieldset class="layui-elem-field" style="width:500px;margin:50px 0 0 300px;" ...

  6. Python学习之高级特性

    切片 在Python基础篇里,我们知道Python的可序列对象可以通过索引号(下标)来引用对象元素,索引号可以由0开始从左向右依次获取,可以从-1开始由右向左获取.这种方法可以帮助我们依次获取我们想要 ...

  7. django之python3.4及以上连接mysql的一些问题记录

    首先,祭出大杀器whl https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient django1.x与django2.x 在项目的写法上有一些区别 ...

  8. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(二)

    本文导航 -7. 安装 PHP0 -8. 安装 MariaDB 数据库 -9. 安装和配置 SSH 服务器 -10. 安装 GCC (GNU 编译器集) -11. 安装 Java 7. 安装 PHP ...

  9. ubuntu上通用解压方式

    ubuntu上通用解压方式 tar xvf *.bin.tar.gz,gz,tar.tgz

  10. 考拉Android统一弹框

    作者:钱成杰 背景 在快速开发的背景下,经历了n个版本后的考拉Android App中已经存在了各种各样看似相同却各有差别的弹框样式.其中包括系统弹框和自定义弹框,并且在线上时常会出现IllegalA ...