HDU 5749 BestCoder Round #84 Colmerauer(暴力贡献)

Colmerauer

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 220    Accepted Submission(s): 94

Problem Description

Peter has an
n×m
matrix M.
Let S(a,b)
be the sum of the weight all a×b
submatrices of M.
The weight of matrix is the sum of the value of all the saddle points in the matrix. A saddle point of a matrix is an element which is both the only largest element in its column and the only smallest element in its row. Help Peter find out all the value ofS(a,b).

Note: the definition of saddle point in this problem may be different with the definition you knew before.

Input

There are multiple test cases. The first line of input contains an integerT,
indicating the number of test cases. For each test case:

The first contains two integers n
and m(1≤n,m≤1000)
-- the dimensions of the matrix.

The next n
lines each contain m
non-negative integers separated by spaces describing rows of matrix
M
(each element of M
is no greater than 106).

Output

For each test case, output an integerW=(∑a=1nb=1ma?b?S(a,b)) mod 232.

Sample Input

3
2 2
1 1
1 1
3 3
1 2 3
4 5 6
7 8 9
3 3
1 2 1
2 3 1
4 5 2

Sample Output

4
600
215

Source

BestCoder Round #84

Recommend

wange2014   |   We have carefully selected several similar problems for you:  5751 5750 5746 5745 5744

题解:

Peter有一个n×m的矩阵M.定义S(a,b)为M的所有大小为a×b的子矩阵的权值和.一个矩阵的权值是这个矩阵所有鞍点的值的和.在矩阵中,一个数在所在行中是唯一的最小值,在所在列中是唯一的最大值,则被称为鞍点.帮助Peter找出所有S(a,b)的值.

输出:

已知一个点的Up,Down,Left,Right,即上下左右的扩展范围,然后计算鞍点对答案的贡献。

把所有可能的矩形的长算出来,得到和,宽也是一样,然后按照乘法原理乘起来就好。

详细题解:BestCoder Round #84 (点击)Orz。。。

AC代码:

//#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<string.h>
#include<algorithm>
#define N 1010
using namespace std;
int n,m;
int a[N][N];
int stk[N],top;
int L[N][N],R[N][N],U[N][N],D[N][N];
int readint()
{
	char c;
	while((c=getchar())&&!(c>='0' && c<='9'));
	int ret= c- 48;
	while((c=getchar())&&( c>='0' && c<='9'))
	ret = ret * 10 + c-48;
	return ret;
}
unsigned int calc(int l,int x,int r)
{
	unsigned int d1=r-x+1;
	unsigned int d2=x-l+1;
	unsigned int ret=d1 * (d1+1) / 2 * d2 + d2* (d2-1)/2 *d1;
	return ret;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			a[i][j]=readint();
			}
		}
		for(int i=1;i<=n;i++)
		{
			top=0;
			for(int j=1;j<=m;j++)
			{
				while(top && a[i][stk[top-1]] > a[i][j])
				--top;
				if(top==0) L[i][j]=1;
				else L[i][j]=stk[top-1]+1;
				stk[top++]=j;
			}
		}
		for(int i=1;i<=n;i++)
		{
			top=0;
			for(int j=m;j>=1;--j)
			{
				while(top && a[i][stk[top-1]] > a[i][j])
				--top;
				if(top==0) R[i][j]=m;
				else R[i][j] = stk[top-1] - 1;
				stk[top++] = j;
			}
		}
		for(int i=1;i<=m;i++)
		{
			top=0;
			for(int j=1;j<=n;j++)
			{
				while(top && a[stk[top-1]][i] < a[j][i])
				--top;
				if(top==0) U[j][i]=1;
				else U[j][i] = stk[top-1]+1;
				stk[top++]=j;
			}
	  }
	  for(int i=1;i<=m;i++)
	  {
			top=0;
			for(int j=n;j>=1;--j)
			{
				while(top && a[stk[top-1]][i] < a[j][i])
				--top;
				if(top==0) D[j][i]=n;
				else D[j][i] = stk[top-1]-1;
				stk[top++]=j;
			}
		}
		unsigned int ans=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				ans += (unsigned int)a[i][j]*calc(L[i][j],j,R[i][j])*calc(U[i][j],i,D[i][j]);
			}
		}
		printf("%u\n",ans);
	}
    return 0;
}
时间: 2024-08-01 10:46:14

HDU 5749 BestCoder Round #84 Colmerauer(暴力贡献)的相关文章

HDU 5748 BestCoder Round #84 Bellovin (LIS)

Bellovin Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 540    Accepted Submission(s): 254 Problem Description Peter has a sequence a1,a2,...,an and he define a function on the sequence -- F

hdu 5748 Bellovin(BestCoder Round #84——最长递增子序列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5748 Bellovin Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 929    Accepted Submission(s): 421 Problem Description Peter has a sequence a1,a2,

HDU 5280 BestCoder Round #47 1001:Senior&#39;s Array

Senior's Array Accepts: 199 Submissions: 944 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 某天学姐姐得到了一个数组A,在这个数组的所有非空区间中,她找出了一个区间和最大的,并把这个区间和定义为这个数组的美丽值. 但是她觉得这个数组不够美,于是决定修理一下这个数组. 学姐姐将会进行一次操作,把原数组中的某个数修改为P(必须修改)

HDU 5281 BestCoder Round #47 1002:Senior&#39;s Gun

Senior's Gun Accepts: 235 Submissions: 977 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 学姐姐是一个酷酷的枪手. 她常常会随身携带n把枪,每把枪有一个攻击力a[i]. 有一天她遇到了m只怪兽,每只怪兽有一个防御力b[j].现在她决定用手中的枪消灭这些怪兽. 学姐姐可以用第i把枪消灭第j只怪兽当且仅当b[j]≤a[i],同时她会获

STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )

STL包含四种不同的二分查找算法,binary_search    lower_bound  upper_bound   equal_range.他们的作用域是已经排序好的的数组. ★binary_search试图在已排序的[first, last)中寻找元素value.如果找到它会返回true,否则返回false,它不返回查找位置. ★iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素. ★iterat

HDU 5682/BestCoder Round #83 1003 zxa and leaf 二分+树

zxa and leaf Problem Description zxa have an unrooted tree with n nodes, including (n−1) undirected edges, whose nodes are numbered from 1 to n. The degree of each node is defined as the number of the edges connected to it, and each node whose degree

hdu 5285 BestCoder Round #48 ($) 1002 种类并查集

// M == 0 有trick... N < 2 也有trick...... 1 #include"iostream" 2 #include"cstdio" 3 #include"cstring" 4 #include"map" 5 using namespace std; 6 int N, M; 7 int rt[100010], w[100010]; 8 int Size[100010], Friend[10001

HDU 5568 - BestCoder Round #63 - sequence2

题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意 : 给一个长度已知的序列, 给一个值k, 问该序列中有多少种长度为k的上升子序列 思路 : 日常读错题..理解成有多少种值不同且长度为k的上升子序列了, 而原意是只要任意两个子序列的下标不同即可 就按官方题解的解法, dp, 用二维数组dp[i][j]位置i的数作为子序列中第j个数的方案数 故遍历序列, 对一个位置i, 它作为序列中第k大的值, 如果在它之前有b[i] > b[j],

BestCoder Round #84

1001,预处理出所有2的幂次数,然后从最大的开始找就行.但是最大的位置应当是从i=min(tot,m)开始,因为如果m很大,比tot还大,那么2^m根本没存下来,或者说num[i]是0,结果就会出现整数除以0的错误了(我一开始就是这样的= =):另外如果m很小,如果n同时很大,不能从tot开始找,因为最大的数不是2^tot,必须从2^m开始找.还好当时凭借直觉这么写然后AC了- -,不然又是WA到死..代码如下: 1 #include <stdio.h> 2 #include <alg