【JZOJ4820】【NOIP2016提高A组模拟10.15】最大化
题目描述
输入
输出
样例输入
3 2
4 0
-10 8
-2 -2
样例输出
4
数据范围
解法
枚举两条扫描线,在这两条扫描线之间的矩阵,可以将之转化为一个序列b[i]=a[i][1..m]。
然后矩阵上的问题就转化成序列上的问题:
给定一个序列,求最长的连续子序列的和为正数的长度。
考虑到是所有区间问题,考虑分治。
对于一个区间[l,r],要求的是跨两半部分的最长长度。
先求出以mid为右端点的最长子区间;
设一个指针指向mid,考虑右移指针。
如果新加入元素是小于0,那么答案不会更优,左指针肯定要右移至少一位才会使得答案平衡;
如果新加入元素大于0,那么考虑把左指针一直左移直到合法子区间极大。
由于左指针至多左移2∗n,时间复杂度为O(nlogn)。
总的时间复杂度为O(n3logn)。
代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define ln(x,y) ll(log(x)/log(y))
#define sqr(x) ((x)*(x))
using namespace std;
const char* fin="max.in";
const char* fout="max.out";
const ll inf=0x7fffffff;
const ll maxn=307;
ll n,m,i,j,k,ans;
ll a[maxn][maxn],b[maxn],sum[maxn][maxn];
ll solve(ll l,ll r){
ll i=0,j=0,k=0,y=0,mid=(l+r)/2,tmp,tmd=0;
if (l==r) return b[l]>0?1:0;
tmp=max(solve(l,mid),solve(mid+1,r));
k=y=0;
for (i=mid;i>=l;i--){
k+=b[i];
if (k>0) tmd=mid-i+1,y=k;
}
tmp=max(tmp,tmd);
j=mid-tmd+1;
i=k=0;
for (i=mid+1;i<=r;i++){
k+=b[i];
if (b[i]>0){
while (j>l && k+y+b[j-1]>0) y+=b[--j];
}else if (b[i]==0){
}else if (j<mid && k+y<=0) y-=b[j++];
if (k+y>0) tmp=max(tmp,i-j+1);
}
return tmp;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%lld%lld",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++) scanf("%lld",&a[i][j]),sum[i][j]=a[i][j]+sum[i][j-1];
for (i=1;i<=m;i++)
for (j=i;j<=m;j++){
for (k=1;k<=n;k++) b[k]=sum[k][j]-sum[k][i-1];
ans=max(ans,solve(1,n)*(j-i+1));
}
printf("%lld",ans);
return 0;
}
启发
当要处理子矩阵问题时,可以用两条扫描线把问题转化到序列上。
处理所有区间问题可以考虑分治。
【JZOJ4820】【NOIP2016提高A组模拟10.15】最大化的更多相关文章
- 【NOIP2016提高A组模拟10.15】最大化
题目 分析 枚举两个纵坐标i.j,接着表示枚举区域的上下边界, 设对于每个横坐标区域的前缀和和为\(s_l\),枚举k, 显然当\(s_k>s_l\)时,以(i,k)为左上角,(j,k)为右下角 ...
- NOIP2016提高A组模拟10.15总结
第一题,就是将原有的式子一步步简化,不过有点麻烦,搞了很久. 第二题,枚举上下边界,维护一个单调队列,二分. 比赛上没有想到,只打了个暴力,坑了80分. 第三题,贪心,最后的十多分钟才想到,没有打出来 ...
- 【NOIP2016提高A组模拟10.15】打膈膜
题目 分析 贪心, 先将怪物按生命值从小到大排序(显然按这个顺序打是最优的) 枚举可以发对少次群体攻击, 首先将所有的群体攻击发出去, 然后一个一个怪物打,当当前怪物生命值大于2,如果还有魔法值就放重 ...
- 【NOIP2016提高A组模拟10.15】算循环
题目 分析 一步步删掉循环, 首先,原式是\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=i}^n\sum_{l=j}^m\sum_{p=i}^k\sum_{q=j}^l1\] 删 ...
- 【JZOJ4819】【NOIP2016提高A组模拟10.15】算循环
题目描述 输入 输出 样例输入 167 198 样例输出 906462341 数据范围 解法 令f(n)=∑ni=1i,g(n)=∑ni=1i2 易得ans=∑ni=1∑mj=1f(n−i+1)∗f( ...
- 【NOIP2016提高A组模拟9.15】Osu
题目 分析 考虑二分答案, 二分小数显然是不可取的,那么我们将所有可能的答案求出来,记录在一个数组上,排个序(C++调用函数很容易超时,手打快排,时间复杂度约为\(O(>8*10^7)\),但相 ...
- 【NOIP2016提高A组模拟8.15】Garden
题目 分析 其实原题就是[cqoi2012][bzoj2669]局部极小值. 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点) ...
- 【JZOJ4784】【NOIP2016提高A组模拟9.15】Map
题目描述 输入 输出 样例输入 4 4 2 1 2 2 3 3 2 3 4 1 2 1 4 样例输出 14 数据范围 样例解释 upd:保证原图连通. "不相交路径"的定义为不存在 ...
- 【NOIP2016提高A组模拟9.15】Map
题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...
随机推荐
- storm-jdbc的使用
最近项目组分配到研究storm-jdbc用法 发现网上关于insert和query方法挺多的,但是自定义方法很少.而且用法上也挺多缺陷.在此自己总结记录一下 JdbcInsertBolt 的核心代码 ...
- numpy库数组属性查看:类型、尺寸、形状、维度
import numpy as np q = np.array([1,2,3,4],dtype=np.complex128) print("数据类型",type(q)) ...
- Ubuntu 解压和压缩总结
1..rar文件 一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具非常简单,下面是具体方法: ubuntu 下r ...
- Redis源码解析:17Resis主从复制之主节点的部分重同步流程及其他
本文主要讲解主节点部分重同步的实现,以及主从复制中的其他功能.本文是Redis主从复制机制的最后一篇文章. 主节点在收到从节点发来的PSYNC命令之前,主节点的部分重同步流程,与完全重同步流程是一样的 ...
- LC327 Count of Range Number
这一题,我们使用了分治法. 首先看时间复杂度为o(n^2),比较naïve的方法: 使用一个数组sum[],长度为原数组长度+1,每一个元素sum[i]为原数组中index0~i-1之和,显然当sum ...
- FileReader详解
一.兼容性 从上图中可以看出IE7.8.9都不支持FileReader对象 二.作用 使用支持FileReader浏览器的用户可以通过一个file input选择一个图像文件将图片显示在页面中,而不用 ...
- Sublime svn 安装
Ctrl + Shift + P 进入 install package 输入svn windows系统选择:TortoiseSVN (在此之前,请确保电脑上已经安装好了TortoiseSVN) li ...
- JNI初级:android studio生成so文件详细过程
本文主要参考blog:http://blog.csdn.net/jkan2001/article/details/54316375 下面是本人结合blog生成so包过程中遇到一些问题和解决方法 (1) ...
- IntelliJ IDEA 17 创建maven项目
参考博客: https://yq.aliyun.com/articles/111053# 部署服务器时 没有Tomcat Server选项
- paip.前端载入时间分析之道优化最佳实践
paip.前端载入时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的载入,看时间...能够排除编程语言的问题and 数据库.. ## ...