风屿
题目描述
风屿是一块 $ n $ 行,$ m $ 列的群岛,第 $ i $ 行第 $ j $ 列记为 $ (i,j) $。
风屿的重力系统很奇怪,$ (i,j) $ 的重力系数 \(g_{i,j}=a_i+b_j\)。\(a,b\) 是两个已知的长度分别为 \(n,m\) 的数组。
我们定义岛 $ (x,y) $ 和 $ (z,w) $ 相邻当且仅当 $ |x-z|+|y-w|=1 $,定义 $ (x,y) $ 和 $ (z,w) $ 连通当且仅当两种情况至少有一种满足:
-
$ (x,y),(z,w) $ 相邻,且 $ g_{x,y}=g_{z,w} $。
-
存在另一个岛 $ (u,v) $ 使得 $ (x,y) $ 和 $ (u,v) $ 连通且 $ (u,v) $ 和 $ (z,w) $ 连通,也就是说,连通关系具有传递性。
我们定义无序互异的岛集 $ {(x_i,y_i)} $ 为同色连通块,当且仅当岛集中任意两岛连通。
找到最大的同色连通块,并求出大小和这样的块的个数。
输入格式
本题多测,第一行一个正整数 $ T $,代表该测试点内测试数据组数。
对于每组测试数据:
第一行 \(n\),\(m\),表示风屿的行数和列数。
接下来一行 $ n $ 个整数,代表 $ a $ 数组。
接下来一行 $ m $ 个整数,代表 $ b $ 数组。
输出格式
$ T $ 行,每行代表该组测试数据的答案(最大块大小和个数)。
样例输入
3
3 4
1 2 2
1 2 3 4
4 5
1 2 2 3
2 3 3 3 4
6 7
1 1 2 2 3 4
1 2 2 2 3 3 3
样例输出
2 4
6 1
6 4
提示
对于 \(100\%\) 的数据,\(1\le T \le 5\),\(1 \le n,m \le 10^5\),\(1 \le a_i,b_i \le 10^9\)。
分析题目,由于同色连通块当中每两个岛都相邻,则其必须是一个矩阵
其次,又因为重力系数,所以同色连通块的两个岛值相等
也就是说,第一问就是求最大矩阵,并且其大小为 \(a\) 数组当中最长连续且相等的序列长度乘以 \(b\) 数组当中最长连续且相等的序列长度
第二问呢?自然就是求有几个这样的矩阵
时间复杂度为 \(O(T(n+m))\)
\(Code:\)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100005;
int a[N],b[N];
int a_siz,a_num,b_siz,b_num;
signed main()
{
int t;scanf("%lld",&t);
while(t--){
int n,m;scanf("%lld%lld",&n,&m);
int tmp=1;
a_siz=a_num=b_siz=b_num=0;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]==a[i-1]) tmp++;
else tmp=1;
if(tmp>a_siz) a_siz=tmp,a_num=1;
else if(tmp==a_siz) a_num++;//如果相等,说明找到了一个等价的矩阵
}
tmp=1;
for(int i=1;i<=m;i++){
scanf("%lld",&b[i]);
if(b[i]==b[i-1]) tmp++;
else tmp=1;
if(tmp>b_siz) b_siz=tmp,b_num=1;
else if(tmp==b_siz) b_num++;
}
printf("%lld %lld\n",a_siz*b_siz,a_num*b_num);
}
return 0;
}