BZOJ2388: 旅行规划
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: 旅行规划相关推荐
- BZOJ2388 : 旅行规划
考虑分块,每块维护两个标记$ts,td$. 那么对于块中一个位置$i$,它的实际值为$i\times td+ts+v_i$. 修改的时候,对于整块,直接打标记,对于零散的暴力修改,然后重构凸壳,时间复 ...
- 【分块】[LUOGU 旅行规划] 分块+二分+凸包优化
题目: 题目链接:[LUOGU 旅行规划] 题解: (由于这个,,我竟然还去写了二维凸包的模板题作为练习,,,然而,一点用都没有,,,,) 先解释一下题面的意思:就是一个区间加的操作,再加上一个区间的 ...
- 青岛旅行规划及玩后感
之前一直属于宅男类型,出去玩也都是周边短途1日游,不需要什么规划,想来去南浔的那次属于最有规划的了,网上订了门票,其他的都是走到哪算到哪. 2012年6月30号的青岛行算是第一次意义上自己的规划旅行, ...
- 离散数学图论旅行规划问题_《图论及其应用》(一)
点击返回目录 一. 定义 1.1 图的基本概念 图或有序对或序偶(P1).有限图/平凡图/非平凡图/空图(P1).顶点数或阶数/边数/重数/重边/环(P1).简单图/复合图(P1).相邻(P2).相关 ...
- 离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...
下面的链接是精华版思路,亮点是对第六问的探讨. 高度概括一下:第一问曼哈顿,第二问用免疫,三问增加任务单,四问增加拣货员,五问改变复核台,六问亮点来探讨~ 有点皮 MathorCup C题 仓内拣货优 ...
- 离散数学图论旅行规划问题_旅游路径规划问题.pdf
参赛密码 (由组委会填写) 第十二届 "中关村青联杯"全 国研 究生 第十二届 "中关村青联杯"全 国研 究生 数学建模竞赛 数学建模竞赛 题 目 旅游路径规划 ...
- Google地图的trip plan是旅行规划的好帮手!
- @bzoj - 2388@ 旅行规划
目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...
- c语言旅行规划问题,利用动态规划法求解旅行商问题(TSP)的C语言实现(一)...
算法改进:通过改进集合操作降低比较次数,利用二进制表示集合.确定元素k是否在集合S中的比较次数为1,从而降低了时间复杂度到O(n2^n) #include #include #include #inc ...
最新文章
- AI战场,李彦宏马化腾马云都在频频刷脸,周鸿祎和他的360在想啥呢?
- window中常用的命令
- JavaScript文本框的操作
- Oracle存储过程中执行DDL操作
- python socket模块作用_python之socket模块详解--小白博客
- [Windows Server 2012] 安装IIS8.5及FTP
- chrome谷歌浏览器script标签引入CLODOP CLodopfuncs.js 跨域报错
- UEFI学习——在qemu上读取设备PCI信息
- 三种坐标系经纬度转化小工具
- html5鼠标悬停图片变淡,鼠标移动悬停在图片上图片变色或半透明变化效果实现...
- 一篇文章带您秒懂地理标志商标注册
- 计算机主板清理,电脑主板脏了如何清洗电脑主板才是正确
- Controlling the Amount of Verbatim Copying in Abstractive Summarization
- Web前端-网站首页和注册界面的实现
- dw网页设计期末设计一个网页_《网页设计与制作Dreamweaver》期末考试试题
- 详细分析MySQL的日志(一)本文原创地址:博客园骏马金龙https://www.cnblogs.com/f-ck-need-u/p/9001061.html
- qmail 相关问题
- 信噪比SNR和EbN0
- 【MATLAB绘图】3sigma即剔除小概率事件功能的使用
- 风扇--DLTAP703SC--单片机--杰力科创