题目描述

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. Logger日志配置级别说明及设置方法、说明

    日志记录器(Logger)是日志处理的核心组件.log4j具有5种正常级别(Level).日志记录器(Logger)的可用级别Level (不包括自定义级别 Level), 以下内容就是摘自log4j ...

  2. 基于mybatis设计简单信息管理系统2

    1.空指针异常 public class CanvasServlet extends HttpServlet { private CanvasService canvasService; privat ...

  3. Docker自学纪实(四)搭建LNMP部署wordpress

    我们在工作中最常用的就是LNMP网站平台 这个架构呢,是整个公司网站的核心 如果对于访问量较小的网站,可以直接在服务器上面部署 而如果是访问量很大的网站,那负载就是个很大的问题. 要么需要再买很多服务 ...

  4. 【vlan-端口配置】

    搭建好拓扑图如下: 分别配置两台终端的ip地址 创建vlan把e0/4/0接口加入到新的vlan中 连通性失败 . 同理在把e0/4/1加入到vlan视图中 连通性成功 : 搭建好拓扑图如下 进入e0 ...

  5. thinkphp centos7 报class POD not found

    没有安装PDO yum install php70w-pdo yum install php70w-mysqlnd 两条命令搞定

  6. 第一章 UNIX 基础知识

    1.1 Unix体系结构 OS定义为一种软件,它控制计算机硬件资源,提供程序运行环境,一般称其为内核(kernel),它体积小,位于环境中心. 内核的接口为系统调用(system call),共用函数 ...

  7. 实时查询引擎 - Facebook Presto 介绍与应用

    1. Presto 是什么   Facebook presto是什么,继Facebook创建了HIVE神器后的又一以SQL语言作为接口的分布式实时查询引擎,可以对PB级的数据进行快速的交互式查询.它支 ...

  8. WPF制作的小时钟

    原文:WPF制作的小时钟 周末无事, 看到WEB QQ上的小时钟挺可爱的, 于是寻思着用WPF模仿着做一个. 先看下WEB QQ的图: 打开VS, 开始动工. 建立好项目后, 面对一个空荡荡的页面, ...

  9. ST表学习

    啊谈不上学习了.复习一下原理留一下板子. $f\left[i,j \right]$表示以$i$为起点,区间长度为${2}^{j}$的区间最值.以最小值为例,即 $min\left(a\left [ k ...

  10. CSS3实现带阴影的弹球

    实现div上下跳动时,底部阴影随着变化 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...