[ARC051D]長方形

题目大意:

给定\(A_{1\sim n}\)和\(B_{1\sim m}(n,m\le2000,|A_i|,|B_i|\le10^5)\),矩阵\(C_{i,j}=A_i+B_j\)。\(q(q\le2000)\)次询问,求坐标不超过\((x,y)\)的最大权值子矩阵的权值。

思路:

用\(maxa[i][j]\)表示\(A_{1\sim i}\)中长度为\(j\)的最大连续子段和,\(maxb\)同理。

对于询问\((x,y)\),答案即为\(\max\{maxa[x][i]\times j+maxb[y][j]\times i\mid i\le x,j\le y\}\)。

\(\max\)内变形后即为\(j\times(maxa[x][i]+\frac{maxb[y][j]\times i}j)\)。括号内的东西可以看作是关于\(\frac{maxb[y][j]}j\)的一次函数,使用李超树维护凸壳即可。

时间复杂度\(\mathcal O(qn\log n)\)。

源代码:

#include<cmath>
#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
typedef long long int64;
const int N=2001,LIM=1e5,SIZE=(LIM<<1|1)<<2;
int a[N],b[N],maxa[N][N],maxb[N][N];
class SegmentTree {
#define _left <<1
#define _right <<1|1
#define mid ((b+e)>>1)
private:
struct Node {
int a,b,tim;
};
Node node[SIZE];
public:
void insert(const int &p,const int &b,const int &e,int i,int j,const int &t) {
if(node[p].tim<t) {
node[p].a=i;
node[p].b=j;
node[p].tim=t;
return;
}
int64 lval1=1ll*node[p].a*b+node[p].b;
int64 rval1=1ll*node[p].a*e+node[p].b;
int64 lval2=1ll*i*b+j,rval2=1ll*i*e+j;
if(lval1<lval2) {
std::swap(lval1,lval2);
std::swap(rval1,rval2);
std::swap(node[p].a,i);
std::swap(node[p].b,j);
}
if(rval1>=rval2||b==e) return;
const double c=1.*(j-node[p].b)/(node[p].a-i);
if(c<=mid) {
insert(p _left,b,mid,node[p].a,node[p].b,t);
node[p].a=i;
node[p].b=j;
} else {
insert(p _right,mid+1,e,i,j,t);
}
}
double query(const int &p,const int &b,const int &e,const double &x,const int &t) const {
if(node[p].tim<t) return -1e15;
double ret=node[p].a*x+node[p].b;
if(b==e) return ret;
if(x<=mid) ret=std::max(ret,query(p _left,b,mid,x,t));
if(x>mid) ret=std::max(ret,query(p _right,mid+1,e,x,t));
return ret;
}
#undef _left
#undef _right
#undef mid
};
SegmentTree t;
int main() {
const int n=getint(),m=getint();
for(register int i=1;i<=n;i++) {
maxa[i][i]=a[i]=a[i-1]+getint();
for(register int j=1;j<i;j++) {
maxa[i][j]=std::max(maxa[i-1][j],a[i]-a[i-j]);
}
}
for(register int i=1;i<=m;i++) {
maxb[i][i]=b[i]=b[i-1]+getint();
for(register int j=1;j<i;j++) {
maxb[i][j]=std::max(maxb[i-1][j],b[i]-b[i-j]);
}
}
const int q=getint();
for(register int p=1;p<=q;p++) {
const int x=getint(),y=getint();
for(register int i=1;i<=x;i++) {
t.insert(1,-LIM,LIM,i,maxa[x][i],p);
}
int64 ans=LLONG_MIN;
for(register int i=1;i<=y;i++) {
ans=std::max(ans,llround(t.query(1,-LIM,LIM,1.*maxb[y][i]/i,p)*i));
}
printf("%lld\n",ans);
}
return 0;
}

[ARC051D]長方形的更多相关文章

  1. PCB成型製程介紹

    PCB成型製程在電子構裝中所扮演的角色 下圖是電腦主機的內部組成 我們將以插在主機板上的一片 USB擴充卡來說明PCB成型製 程在電子構裝中所扮演的角色 PCB成型製程的子製程 USB擴充卡要插入主機 ...

  2. [R] 繪圖 Par 函数

    本篇內文主引用 https://zhuanlan.zhihu.com/p/21394945 之內容再稍加整理並參照下方有用資源 [rdocumentation] https://www.rdocume ...

  3. [題解/狀壓dp]POJ_2411_Mondriaan's dream

    关于“我读过很多书,到后来大部分都被我忘记了,那阅读的意义是什么?”的疑问,我看过最巧妙的一个回答:当我还是个孩子的时候,我吃过很多的食物,大部分已经一去不复返而且被我忘记了,但可以肯定的是,它们中的 ...

  4. Halcon算子函数

    Chapter_1_:Classification 1.1  Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一個訓練樣本添加到一個高斯混合模型的 ...

  5. 妙方之解决matplotlib的图例里的中文呈现小方形

    妙方之解决matplotlib的图例里的中文呈现小方形 分析思路: 每个中文都对应地呈现一个小方形, 不多也不少. 不能说是乱码. 应该是matplotlib的默认字库不支持中文造成的. 应对办法: ...

  6. PHP 計算字符串長度函數

    PHP內置的字符串長度函數strlen無法正確處理中文字符串,它得到的只是字符串所占的字節數.對於GB2312的中文編碼,strlen得到的值是漢字個數的2倍,而對於UTF-8編碼的中文,就是3倍的差 ...

  7. C#使用多态求方形面积周长和圆的面积周长

    class class1 { public static void Main(string[] args) { //使用多态求矩形面积与周长和圆的面积与周长 Shape cl = ); double ...

  8. Html5 Css实现方形图片 圆形显示

    <!doctype html><html><head><meta charset="utf-8"><title>方形图片 ...

  9. canvas应用——将方形图片处理为圆形

    上段时间在项目中需要将方形图片处理为圆形图片,你可能会说直接用css设置border-radius: 50%就可以了,但是项目中还要将此图片的圆形图片作为一部分利用canvas将其绘制到一张背景图上面 ...

随机推荐

  1. 【洛谷 P3203】 [HNOI2010]弹飞绵羊(LCT)

    题目链接 把每个点和能跳到的点连边,于是就构成了一个森林. 查询操作就是该点到根的路径长度,修改操作就相当于删边再重新连边. 显然是\(LCT\)的强项. 查询时\(access(x),splay(x ...

  2. 伪ajax操作

    什么是伪Ajax操作? 说白了就是假的ajax操作,但是它和正常的ajax操作的目的是一样的,把前端的信息发送到后台 先看一下代码吧! ajax.html <form action=" ...

  3. 关于linux系统如何实现fork的研究(一)【转】

    转自:http://www.aichengxu.com/linux/4157180.htm 引言 fork函数是用于在linux系统中创建进程所使用,而最近看了看一个fork()调用是怎么从应用到gl ...

  4. USB 3.0传输规格

    通用序列总线(USB) 从1996问世以来,一统个人电脑外部连接界面,且延伸至各式消费性产品,早已成为现代人生活的一部分.2000年发表的USB 2.0 High-speed规格,提供了480Mbps ...

  5. pyQt: eg3

    import sys import urllib2 from PyQt4 import QtCore from PyQt4 import QtGui class Form(QtGui.QDialog) ...

  6. 在flask中返回requests响应

    在flask服务端,有时候需要使用requests请求其他url,并将响应返回回去.查阅了flask文档,About Responses,可以直接构造响应结果进行返回. If a tuple is r ...

  7. BootStrap的table表格,栅格系统,form表单的样式

    BootStrap BootStrap的简介 1.    什么是Bootstrap 由两个前端设计师开发的一个前端的框架(Html,css,js) 简化了程序员写css的代码 2.    为什么使用B ...

  8. HDU 4725 The Shortest Path in Nya Graph(spfa+虚拟点建图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4725 题目大意:有n层,n个点分布在这些层上,相邻层的点是可以联通的且距离为c,还有额外给出了m个条边 ...

  9. Elasticsearch分片&副本分配

    集群索引中可能由多个分片构成,并且每个分片可以拥有多个副本,将一个单独的索引分为多个分片,可以处理不能在单一服务器上运行的 大型索引. 由于每个分片有多个副本,通过副本分配到多个服务器,可以提高查询的 ...

  10. oracle创建计划任务

    特别提示: oracle是执行完任务,才按照interval去计算下次执行时间!!! 为精确每个5分钟执行一个任务,必须自己计算时间. 如:trunc_minute(sysdate)+/ create ...