http://www.lydsy.com/JudgeOnline/problem.php?id=2388

  带区间加修改,求区间内的最大前缀和。

  设sum[i]代表i的前缀和,tag[i][j]代表i到j位置上每个数字都加上了tag[i][j],add[i][j]代表i到j位置上每个位置的前缀和都加上了add[i][j]。

  对于区间[l,r],设最大答案为ans,ans=max{add[l][r]+tag[l][r]×(i-l+1)+sum[i]|l≤i≤r}。

  设x=(i-l+1),y=sum[i],则有ans=add[l][r]+tag[l][r]×x+y,可以化简为y=-tag[l][r]×x+ans-add[l][r],就是给定一些点,要最大化过某个点且斜率给定的直线的截距,维护上凸壳即可。

  所以我们分块,对于每一块维护上凸壳,查询操作O(√nlog(n)),修改O(√n)。

  注意重建某一块的上凸壳之前要标记下传。

#include<bits/stdc++.h>
const int maxn=100015,maxb=415;
typedef long long int64;
using namespace std;
int n,m,num,siz,idx[maxn];
int64 sum[maxn];
struct Tblock{static const int maxsiz=415;static const double eps=1e-9;int l,r,top;int64 add,tag;struct Tpoint{int64 x,y;}stk[maxsiz];void modify(int64 _add,int64 _tag){add+=_add;tag+=_tag;}double slope(Tpoint a,Tpoint b){return 1.0*(b.y-a.y)/(b.x-a.x);}void push_down(){for (int i=l;i<=r;++i) sum[i]+=tag*(i-l+1)+add;tag=add=0;}void rebuild(){top=0;for (int i=l;i<=r;++i){Tpoint cur=(Tpoint){i-l+1,sum[i]};while (top>1&&slope(stk[top-1],stk[top])+eps<slope(stk[top],cur)) --top;stk[++top]=cur;}stk[0]=(Tpoint){stk[1].x-1,(int64)-1e18};stk[top+1]=(Tpoint){stk[top].x+1,(int64)-1e18};}int64 query(){double k=-tag;int l=1,r=top;while (1){int mid=(l+r)>>1;double lk=slope(stk[mid-1],stk[mid]),rk=slope(stk[mid],stk[mid+1]);if (lk+eps>=k&&rk<=eps+k) return stk[mid].y+tag*stk[mid].x+add;else if (rk>eps+k) l=mid+1;else r=mid-1;}}
}block[maxb];
void init_block(){siz=sqrt(n);for (int j,i=1;i<=n;i=j){for (++num,j=i;j-i+1<=siz&&j<=n;++j) idx[j]=num;block[num].l=i;block[num].r=j-1;block[num].rebuild();}
}
void init(){scanf("%d",&n);for (int i=1;i<=n;++i){scanf("%lld",&sum[i]);sum[i]+=sum[i-1];}init_block();
}
void modify(int l,int r,int64 v){if (idx[l]==idx[r]){block[idx[l]].push_down();for (int i=l;i<=r;++i) sum[i]+=v*(i-l+1);for (int i=r+1;i<=block[idx[r]].r;++i) sum[i]+=v*(r-l+1);block[idx[l]].rebuild();for (int i=idx[l]+1;i<=num;++i) block[i].modify(v*(r-l+1),0);}else{block[idx[l]].push_down();block[idx[r]].push_down();for (int i=l;i<=block[idx[l]].r;++i) sum[i]+=v*(i-l+1);for (int i=block[idx[r]].l;i<=r;++i) sum[i]+=v*(i-l+1);for (int i=r+1;i<=block[idx[r]].r;++i) sum[i]+=v*(r-l+1);block[idx[l]].rebuild();block[idx[r]].rebuild();for (int i=idx[l]+1;i<=idx[r]-1;++i) block[i].modify(v*(block[idx[l]].r-l+1+siz*(i-idx[l]-1)),v);for (int i=idx[r]+1;i<=num;++i) block[i].modify(v*(r-l+1),0);}
}
int64 query(int l,int r){int64 res=-1e18;if (idx[l]==idx[r])for (int i=l;i<=r;++i) res=max(res,sum[i]+block[idx[i]].add+block[idx[i]].tag*(i-block[idx[i]].l+1));else{for (int i=l;i<=block[idx[l]].r;++i) res=max(res,sum[i]+block[idx[i]].add+block[idx[i]].tag*(i-block[idx[i]].l+1));for (int i=block[idx[r]].l;i<=r;++i) res=max(res,sum[i]+block[idx[i]].add+block[idx[i]].tag*(i-block[idx[i]].l+1));for (int i=idx[l]+1;i<=idx[r]-1;++i) res=max(res,block[i].query());}return res;
}
void work(){scanf("%d",&m);for (int i=1;i<=m;++i){int t,l,r;int64 v;scanf("%d%d%d",&t,&l,&r);switch (t){case 0:scanf("%lld",&v);modify(l,r,v);break;case 1:printf("%lld\n",query(l,r));break;}}
}
int main(){init();work();return 0;
}

my code

转载于:https://www.cnblogs.com/iamCYY/p/4720066.html

BZOJ2388: 旅行规划相关推荐

  1. BZOJ2388 : 旅行规划

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

  2. 【分块】[LUOGU 旅行规划] 分块+二分+凸包优化

    题目: 题目链接:[LUOGU 旅行规划] 题解: (由于这个,,我竟然还去写了二维凸包的模板题作为练习,,,然而,一点用都没有,,,,) 先解释一下题面的意思:就是一个区间加的操作,再加上一个区间的 ...

  3. 青岛旅行规划及玩后感

    之前一直属于宅男类型,出去玩也都是周边短途1日游,不需要什么规划,想来去南浔的那次属于最有规划的了,网上订了门票,其他的都是走到哪算到哪. 2012年6月30号的青岛行算是第一次意义上自己的规划旅行, ...

  4. 离散数学图论旅行规划问题_《图论及其应用》(一)

    点击返回目录 一. 定义 1.1 图的基本概念 图或有序对或序偶(P1).有限图/平凡图/非平凡图/空图(P1).顶点数或阶数/边数/重数/重边/环(P1).简单图/复合图(P1).相邻(P2).相关 ...

  5. 离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...

    下面的链接是精华版思路,亮点是对第六问的探讨. 高度概括一下:第一问曼哈顿,第二问用免疫,三问增加任务单,四问增加拣货员,五问改变复核台,六问亮点来探讨~ 有点皮 MathorCup C题 仓内拣货优 ...

  6. 离散数学图论旅行规划问题_旅游路径规划问题.pdf

    参赛密码 (由组委会填写) 第十二届 "中关村青联杯"全 国研 究生 第十二届 "中关村青联杯"全 国研 究生 数学建模竞赛 数学建模竞赛 题 目 旅游路径规划 ...

  7. Google地图的trip plan是旅行规划的好帮手!

  8. @bzoj - 2388@ 旅行规划

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

  9. c语言旅行规划问题,利用动态规划法求解旅行商问题(TSP)的C语言实现(一)...

    算法改进:通过改进集合操作降低比较次数,利用二进制表示集合.确定元素k是否在集合S中的比较次数为1,从而降低了时间复杂度到O(n2^n) #include #include #include #inc ...

最新文章

  1. AI战场,李彦宏马化腾马云都在频频刷脸,周鸿祎和他的360在想啥呢?
  2. window中常用的命令
  3. JavaScript文本框的操作
  4. Oracle存储过程中执行DDL操作
  5. python socket模块作用_python之socket模块详解--小白博客
  6. [Windows Server 2012] 安装IIS8.5及FTP
  7. chrome谷歌浏览器script标签引入CLODOP CLodopfuncs.js 跨域报错
  8. UEFI学习——在qemu上读取设备PCI信息
  9. 三种坐标系经纬度转化小工具
  10. html5鼠标悬停图片变淡,鼠标移动悬停在图片上图片变色或半透明变化效果实现...
  11. 一篇文章带您秒懂地理标志商标注册
  12. 计算机主板清理,电脑主板脏了如何清洗电脑主板才是正确
  13. Controlling the Amount of Verbatim Copying in Abstractive Summarization
  14. Web前端-网站首页和注册界面的实现
  15. dw网页设计期末设计一个网页_《网页设计与制作Dreamweaver》期末考试试题
  16. 详细分析MySQL的日志(一)本文原创地址:博客园骏马金龙https://www.cnblogs.com/f-ck-need-u/p/9001061.html
  17. qmail 相关问题
  18. 信噪比SNR和EbN0
  19. 【MATLAB绘图】3sigma即剔除小概率事件功能的使用
  20. 风扇--DLTAP703SC--单片机--杰力科创

热门文章

  1. Werkzeug routing
  2. EventTarget
  3. Vue.js 入门案例
  4. linux 配置java环境
  5. 2.6 更多导数的例子
  6. CentOS7没有ftp命令的解决方法
  7. nofollow标签_网站Nofollow标签的应用场景
  8. python 如何做密码对话框_Python GUI教程(八):在主窗口中调用对话框
  9. VMware SDS 之四: VSAN的技术细节 (含VSAN 6.0、6.1版的新内容)
  10. VMware NSX 6组件通信图