CodeForces 263E Rhombus
洛谷题目页面传送门 & CodeForces题目页面传送门
给定一个\(n\)行\(m\)列的矩阵,第\(i\)行\(j\)列为\(a_{i,j}\),以及一个常数\(s\in\left[1,\left\lceil\dfrac{\min(n,m)}2\right\rceil\right]\),求一个正整数对\((a,b)(a\in[s,n-s+1],b\in[s,m-s+1])\)使得\(f(a,b)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\max(0,s-(|i-a|+|j-b|))a_{i,j}\)最大。
\(n,m\in\left[1,10^3\right]\)。
将矩阵上每格对函数\(f\)值的贡献的系数画出来,会发现它是个斜着的正方形,中心系数等于\(s\),往外\(1\)层系数减\(1\),减到\(0\)为止,如下图。
枚举中心点,可以得到\(\mathrm O(nm)\)个这样的正方形。现在问题是怎么快速求出所有正方形的系数乘格子内的数之和,即所有中心点的函数值。假设我们已经知道了\(f(i,j)\),现在想知道\(f(i,j+1)\)。不妨把这两个正方形画出来,看它们相差什么。
如上图,是\(2\)个相邻的\(s=3\)的正方形,紫色的数字是此格子内红色系数减蓝色系数。不难发现,左边一半是一个差都是\(-1\)、高为\(s=3\)、直角顶点在底边左侧的等腰直角三角形,右边一半是一个差都是\(1\)……底边右侧……。由此可以归纳出,设\(trl_{i,j}\)表示底边中点为\((i,j)\)、高为\(s\)、直角顶点在底边左侧的等腰直角三角形内元素之和,\(trr_{i,j}\)表示……底边右侧……,则\(f(i,j)=f(i,j-1)-trl_{i,j-1}+trr_{i,j}\)。假设我们已经知道了\(trl,trr\)数组,那么可以\(\forall i\in[s,n-s+1]\),暴力用对角线前缀和\(\mathrm O(s)\)求出\(f(i,s)\),然后\(\forall i\in[s,n-s+1],\forall j\in(s,m-s+1]\),用上面那个关系式递推求出\(f(i,j)\),总复杂度为\(\mathrm O(nm)\)。
现在问题转化为怎么快速求出\(trl,trr\)数组。以\(trl\)为例,先画出相邻两个三角形。
如上图,是两个相邻的\(s=3\)的三角形,紫色的数字是此格子内红色系数减蓝色系数。又不难发现,左边的三角形轮廓的差都是\(-1\),右边一列的差都是\(1\)。这个轮廓的和和列的和可以维护列前缀和\(Sum1\)、副对角线前缀和\(Sum2\)(在同一条副对角线上当且仅当行列和相等)、主对角线前缀和\(Sum3\)(在同一条主对角线上当且仅当行列差相等)搞定。于是就有了一个\(trl_{i,j},trl_{i,j-1}\)的关系式。那么可以\(\forall i\in[s,n-s+1]\),暴力用列前缀和\(\mathrm O(s)\)求出\(trl_{i,s}\),然后\(\forall i\in[s,n-s+1],\forall j\in(s,m]\),用关系式递推求出\(trl_{i,j}\),总复杂度为\(\mathrm O(nm)\)。\(trr\)求法类似。
\(\mathrm O(nm)\)与处理完\(3\)个前缀和,\(trl,trr\)就可以\(\mathrm O(nm)\)求出来了,那么\(f\)也可以\(\mathrm O(nm)\)求出来了,最后找最大值即可。总复杂度\(\mathrm O(nm)\)。
下面贴代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mp make_pair
#define X first
#define Y second
const int N=1000,M=1000;
int n/*矩阵行数*/,m/*矩阵列数*/,s/*常数*/;
int a[N+1][M+1];//矩阵
int Sum1[M+1][N+1]/*列前缀和*/,Sum2[N+M+1][M+1]/*副对角线前缀和*/,Sum3[2*N+1][M+1]/*主对角线前缀和,由于行列差可能是负数,所以平移max(n,m)个单位*/;
int sum1(int x,int l,int r){return l>r?0:Sum1[x][r]-Sum1[x][l-1];}//列区间和
int sum2(int x,int l,int r){return l>r?0:Sum2[x][r]-Sum2[x][l-1];}//副对角线区间和
int sum3(int x,int l,int r){return l>r?0:Sum3[x+max(n,m)][r]-Sum3[x+max(n,m)][l-1];}//主对角线区间和
int trl[N+1][M+1],trr[N+1][M+1];//朝左、朝右三角形
int rhm[N+1][M+1];//正方形,即f函数
signed main(){
cin>>n>>m>>s;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%lld",a[i]+j);
//预处理前缀和开始
for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)Sum1[i][j]=Sum1[i][j-1]+a[j][i];
for(int i=1;i<=n+m;i++)for(int j=1;j<=n;j++)Sum2[i][j]=Sum2[i][j-1]+(1<=i-j&&i-j<=m?a[j][i-j]:0);
for(int i=-max(n,m);i<=max(n,m);i++)for(int j=1;j<=n;j++)Sum3[i+max(n,m)][j]=Sum3[i+max(n,m)][j-1]+(1<=j+i&&j+i<=m?a[j][j+i]:0);
//预处理前缀和结束
for(int i=s;i<=n-s+1;i++){//算trl
for(int j=1;j<=s;j++)trl[i][s]+=sum1(j,i-j+1,i+j-1);//暴力算边上的trl
for(int j=s+1;j<=m;j++)trl[i][j]=trl[i][j-1]+sum1(j,i-s+1,i+s-1)-sum2(i+j-s,i-s+1,i)-sum3(j-s-i,i+1,i+s-1);//用关系式递推其他trl
}
for(int i=s;i<=n-s+1;i++){//算trr,与trl类似
for(int j=m;j>=m-s+1;j--)trr[i][m-s+1]+=sum1(j,i-(m-j+1)+1,i+(m-j+1)-1);
for(int j=m-s;j;j--)trr[i][j]=trr[i][j+1]+sum1(j,i-s+1,i+s-1)-sum3(j+s-i,i-s+1,i)-sum2(i+j+s,i+1,i+s-1);
}
// for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)printf("tr(%lld,%lld)=(%lld,%lld)\n",i,j,trl[i][j],trr[i][j]);
for(int i=s;i<=n-s+1;i++){//算rhm
for(int j=0;j<s;j++)rhm[i][s]+=(s-j)*(sum2(i-j+s,i-j,i)+sum3(s-(i+j),i+1,i+j)+sum2(i+j+s,i,i+j-1)+sum3(s-(i-j),i-j+1,i-1));//暴力算边上的rhm
for(int j=s+1;j<=m-s+1;j++)rhm[i][j]=rhm[i][j-1]+trr[i][j]-trl[i][j-1];//用关系式递推其他rhm
}
// for(int i=s;i<=n-s+1;i++)for(int j=s;j<=m-s+1;j++)printf("rhm[%lld][%lld]=%lld\n",i,j,rhm[i][j]);
pair<int,pair<int,int> > mx(0,mp(0,0));
for(int i=s;i<=n-s+1;i++)for(int j=s;j<=m-s+1;j++)mx=max(mx,mp(rhm[i][j],mp(i,j)));//找最大值
cout<<mx.Y.X<<" "<<mx.Y.Y;
return 0;
}
CodeForces 263E Rhombus的更多相关文章
- Codeforces 263E
Codeforces 263E 原题 题目描述:一个\(n \times m\)的矩阵,每格有一个数,给出一个整数\(k\),定义函数\(f(x, y)\): \[f(x, y)=\sum_{i=1} ...
- Codeforces Round #569 (Div. 2)A. Alex and a Rhombus
A. Alex and a Rhombus 题目链接:http://codeforces.com/contest/1180/problem/A 题目: While playing with geome ...
- Codeforces Round #569 (Div. 2) 题解A - Alex and a Rhombus+B - Nick and Array+C - Valeriy and Dequ+D - Tolik and His Uncle
A. Alex and a Rhombus time limit per test1 second memory limit per test256 megabytes inputstandard i ...
- [Codeforces] Alex and a Rhombus
A. Alex and a Rhombus time limit per test 1 second memory limit per test 256 megabytes input standar ...
- Codeforces Round #277.5 (Div. 2)
题目链接:http://codeforces.com/contest/489 A:SwapSort In this problem your goal is to sort an array cons ...
- Codeforces Round #277.5 (Div. 2)-D. Unbearable Controversy of Being
http://codeforces.com/problemset/problem/489/D D. Unbearable Controversy of Being time limit per tes ...
- Codeforces Round #277 (Div. 2 Only)
A:SwapSort http://codeforces.com/problemset/problem/489/A 题目大意:将一个序列排序,可以交换任意两个数字,但要求交换的次数不超过n,输出任意一 ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
随机推荐
- 【剑指Offer】面试题04. 二维数组中的查找
题目 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 示例: 现 ...
- 详解BurpSuite软件 请求包 HTTP (9.23 第十天)
HTTP协议基础 HTTP:HyperText Transfer Protocol,超文本传输协议 1.协议特点: 简单快速,请求方式get post head等8中请求方式 无连接(一次请求就断开) ...
- UVA - 12627 Erratic Expansion(奇怪的气球膨胀)(递归)
题意:问k小时后,第A~B行一共有多少个红气球. 分析:观察图可发现,k小时后,图中最下面cur行的红气球个数满足下式: (1)当cur <= POW[k - 1]时, dfs(k, cur) ...
- 微软于 snapcraft 上发布 Visual Studio Code 的 Snap 打包版本
微软在 snapcraft 上发布了 Visual Studio Code 的 Snap 打包版本 .Snap 是 Canonical 主导开发的应用打包格式,与 Flatpak 和 AppImage ...
- 关于RxJS 处理多个Http请求 串行与并行方法
mergeMap mergeMap 操作符用于从内部的 Observable 对象中获取值,然后返回给父级流对象. 合并 Observable 对象 123456 import { of } from ...
- 当DIV内出现滚动条,fixed实效怎么办?
sticky 盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位.在所有情况下( ...
- Java8大排序算法
一.冒泡排序 基本思想:通过对待排序序列此前向后,依次比较相邻元素的值,若发现逆序则进行交换,使得较大的值从前面移动到后面, 类似于水下的气泡一样(是所有排序算法中效率最低的) publi ...
- UVALive 3977 BFS染色
这个题意搞了半天才搞明白 就是如果定义一个d-summit,即从该点到另一个更高的点,经过的路径必定是比当前点低至少d高度的,如果该点是最高点,没有比他更高的,就直接视为顶点 其实就是个BFS染色,先 ...
- tomcat的8080,8009,8443,8005都是什么端口
<Server port="8005" shutdown="SHUTDOWN"> 远程停服务端口<Connector port="8 ...
- 读取cookie、写进cookie方法
整理 读取cookie.写进cookie方法. //设置cookies中的值 function setCookie(name, value) { var Days = 30; var exp = ne ...