WOJ 643 Soul Artist 坐标变换+矩阵前缀和

Input file: standard inputOutput file: standard output Time limit: 1 secondMemory limit: 512 mebibytes

Last year, there were three soul artist in the team Abysswatcher. They were all addicted to painting, even when they were on the train. One day, they want to paint a paper. Iniii-th step, they choose a core grid (xi,yi)(x_i, y_i)(xi,yi) and paint all the grid near it (the Manhattan distance distance between the core and other grids are no more thanrir_iri). After some operates, they want to know the maximum times they painted the same grid.

Input

Three integers n,m,tn, m, tn,m,t(1≤n,m≤2000,1≤t≤2×1051 \le n, m \le 2000, 1 \le t \le 2 \times 10^51n,m2000,1t2×105)in one line. nnn and mmm represent the length and the width of the paper. ttt represents the times they painted.

In the following ttt lines, the iii-th contains three non-negative integers xi,yi,rix_i, y_i, r_ixi,yi,ri (1≤xi−ri,xi+ri≤n1 \le x_i - r_i, x_i + r_i \le n1xiri,xi+rin,1≤yi−ri,yi+ri≤m1 \le y_i - r_i, y_i + r_i \le m1yiri,yi+rim).

Output

Two integers in one line, represent the maximum times they painted the same grid and the number of such grid.

Examples

Input 1

6 6 4
2 2 1
2 3 1
3 2 0
3 4 2

Output 1

3 2

Note

The sample looks like this. The "Manhattan distance" of two points A,BA, BA,B equals to ∣Ax−Bx∣+∣Ay−By∣|A_x - B_x| + |A_y - B_y|AxBx+AyBy.

\ 1 2 3 4 5 6 -> x
1     1 1 1
2 1 2 3 2 1
3   3 2 1 1 1
4     1 1 1
5       1
6
|
v
y

        这题的话如果暴力修改O(N^4)果断超时,当时读题的时候就有深深的预感,可以用矩阵前缀和(或者说BIT,但是没必要啊……),但是他是曼哈顿距离,是斜的。这个也好解决,大概用一个横纵坐标的变换就行了。当时就是这么想的,至于具体变换的方法,打算先放放,去调其他的题了,然后就放到了最后……再次追悔莫及,这个变换其实也是显而易见的。

        首先简单的说说矩阵前缀和,对于普通一维区间前缀和,我们在区间左端点+1,右端点-1,然后求某一个具体值的时候就求和即可。至于矩阵前缀和,假设我们要修改左上点(x1,y1)和右下点(x2,y2)对应的矩阵区间,我们对[x1,y1]加1,[x1,y2+1]减1,[x1+1,y2]减1,[x2+1,y2+1]加1,然后求前缀和即可,这里的二维数组前缀和是指以[x,y]为右下角,起始点为左上角的矩阵中数字之和。好像和KD的同学讲过,然后这题也是类似。

        至于对映的方式,一个点分别在两个对角线上,我们新的左边的x'和y'分别就表示两个所在的两个对角线的编号。我们发现,一个区域刚好是一个菱形(正方形),如果转一下恰好是矩形。用了映射过来的新坐标,会发现也恰好是一个矩形。然后用矩阵前缀和即可了。具体对应的话是(x,y)对应(x-y+m,x+y-1)。代码如下,其实好短的,好后悔当时不去写啊:

#include<bits/stdc++.h>

using namespace std;

int c[5000][5000];
int n,m,q,ans=0,t=0;

int main()
{
	scanf("%d%d%d",&n,&m,&q);
	memset(c,sizeof(c),0);
	for(int i=1;i<=q;i++)
	{
		int x,y,r,x1,y1,x2,y2;
		scanf("%d%d%d",&x,&y,&r);
		x1=x-r-y+m,y1=x-r+y-1;
		x2=x+r-y+m,y2=x+r+y-1;
		c[x2][y2]++;
		c[x2][y1-1]--;
		c[x1-1][y2]--;
		c[x1-1][y1-1]++;
	}
	for(int i=1;i<=m+n;i++)
		for(int j=1;j<=n+m;j++)
			c[i][j]+=c[i-1][j]+c[i][j-1]-c[i-1][j-1];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int x=i-j+m;
			int y=i+j-1;
			if (c[x][y]>ans) ans=c[x][y],t=1;
			else if (c[x][y]==ans) t++;
		}
	printf("%d %d\n",ans,t);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值