woj-Soul Artist

Input file: standard input
Output file: standard output 
Time limit: 1 second
Memory 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. In ii-th step, they choose a core grid (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 than r_iri). After some operates, they want to know the maximum times they painted the same grid.

Input

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

In the following tt lines, the ii-th contains three non-negative integers x_i, y_i, r_ixi,yi,ri (1 \le x_i - r_i, x_i + r_i \le n1xiri,xi+rin1 \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,B equals to |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
题目大意:还是比较容易懂得,在每次修改时给出一个点的坐标以及范围大小,从这个点开始出发到在范围内能到达的点就加一,求最大的值一级出现次数
思路
     对于这道题,一开始值为零,而且是先修改在查询,那么我们容易想到前缀和,并且我们能发现,每次修改的时候的范围是一个菱形,通过旋转能变成一个矩形
所以我们可以通过坐标变换来使其成为一个矩形(实际上变为矩形后,矩形中所包括的点其实大于菱形的,但是没有关系,因为问题求的是最大值,没有求整个图,所以我们可以通过坐标的映射去求(实际上不是正好对应的)
至于坐标变换,我可以两条对角线;来作为xy轴,其中需要注意的是,我们求主对角线的标号是x-y+m而不是x-y+m)%m,其实很简单,对角线的数量一定大于m和n
二维前缀和参见基神的教学啦啦啦
ac代码:
#include<cstdio>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
int n,m,q;
int mp[5000][5000];
int ans=-1;
int main()
{
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        ans=-1;
        memset(mp,0,sizeof(mp));
        while(q--)
        {
            int x,y,d;
            scanf("%d%d%d",&x,&y,&d);
            int x1=x-d-y+m;
            int x2=x+d-y+m;
            int y1=y-d+x;
            int y2=y+d+x;
            mp[x1][y1]++;
            mp[x1][y2+1]--;
            mp[x2+1][y1]--;
            mp[x2+1][y2+1]++;
        }
        for(int i=1;i<=n+m;i++)
        {
            int tmp=0;
            for(int j=1;j<=n+m;j++)
            {
                tmp+=mp[i][j];
                mp[i][j]=mp[i-1][j]+tmp;
            }
        }
        int cnt;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                int x=i-j+m;
                int y=i+j;
                if(mp[x][y]>=ans)
                {
                    if(mp[x][y]==ans)
                    cnt++;
                    else{
                    ans=mp[x][y];
                    cnt=1;
                    }
                }

                    //cout<<mp[x][y];
            }
           // cout<<endl;
        }
        cout<<ans<<' '<<cnt<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值