题目描述

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. 洛谷P1437 [HNOI2004]敲砖块(dp)

    题目背景 无 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 ...

  2. BZOJ1509: [NOI2003]逃学的小孩(树的直径)

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1126  Solved: 567[Submit][Status][Discuss] Description ...

  3. python--Matplotlib(一)

    基础知识薄弱的同学可以看看一下博客 https://www.cnblogs.com/dev-liu/p/pandas_plt_basic.html https://blog.csdn.net/Notz ...

  4. Apache2服务配置ubuntu16.04+django1.11

    话不多说直接上步骤 环境 Ubuntu 16.04 Python 3.5.2 Django 1.11 Apache 2.4 1.Apache2安装 sudo apt-get install apach ...

  5. SGU495 概率DP

    Kids and Prizes ICPC (International Cardboard Producing Company) is in the business of producing car ...

  6. 将Mnist手写数字库转化为图片形式 和标签形式

    Mnist 数据文件有两种,一种是图片文件,一种是标签文件,那么如何把他们解析出来呢? (1)解析图片文件 可以看出在train-images.idx3-ubyte中,第一个数为32位的整数(魔数,图 ...

  7. python-1基础总结

    输入  >>> name = input() 1--如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义,可以自己试 ...

  8. 笔记-scrapy-extentions

    笔记-scrapy-extentions 1.      extentions 1.1.    开始 The extensions framework provides a mechanism for ...

  9. Jenkins拾遗--第三篇(用户权限管理)

    采访过很多实用Jenkins的同学,发现Jenkins的安全是一个很薄弱的地方.很多公司用作生产部署的Jenkins安全管理都不是很规范,就更别提测试用的Jenkins了. 其实Jenkins是一个很 ...

  10. 4G来临,短视频社交分享应用或井喷

    因为工作的原因,接触短视频社交应用的时间相对较多,不管是自家的微视,还是别人家的Vine.玩拍.秒拍等,都有体验过.随着时间的推移,我愈发感受到有一股似曾相识的势能正在某个地方慢慢积聚,直到今天我才猛 ...