题意:给你一个n*m的矩阵 ,每个位置都有一个字符并且都有一个值,现在需要找到一个p*q的子矩阵, 原来的矩阵可以由现在这个矩阵无限复制然后截取其中的一部分得到,并且要求 子矩阵里最大的值 * (p+1)*(q+1)的值最小。

题解:对于每一行处理出可能的循环节长度, 然后找到一个长度是所有行的循环节, 对于列同样处理。然后问题就变成了对n*m所有的p*q的子矩阵的找到最小的最大值。这个操作用单调队列维护。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e6 + ;
string s, ss;
int val[N];
int nx[N];
int n, m;
inline int id(int x, int y){
return m * x + y;
}
int cnt[N];
void get_nt(int u){
nx[] = -;
int j = , k = -;
while(j < m){
if(k == - || s[id(u,j)] == s[id(u,k)]) nx[++j] = ++k;
else k = nx[k];
}
int pos = m;
while(pos != -){
cnt[m-pos]++;
pos = nx[pos];
}
}
void get_nt_(int u){
nx[] = -;
int j = , k = -;
while(j < n){
if(k == - || s[id(j,u)] == s[id(k,u)]) nx[++j] = ++k;
else k = nx[k];
}
int pos = n;
while(pos != -){
cnt[n-pos]++;
pos = nx[pos];
}
}
int a[N];
LL mx[N];
int main(){
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++){
cin >> ss;
s += ss;
}
for(int i = ; i < n*m; i++)
scanf("%d", &val[i]);
int p = , q = ;
memset(cnt, , sizeof(cnt));
for(int i = ; i < n; i++) get_nt(i);
for(int i = ; i <= m; i++){
if(cnt[i] == n) {
p = i;
break;
}
}
memset(cnt, , sizeof(cnt));
for(int i = ; i < m; i++) get_nt_(i);
for(int i = ; i <= n; i++){
if(cnt[i] == m) {
q = i;
break;
}
}
/// q*p
for(int i = ; i < n; i++){
int l = , r = -;
for(int j = ; j < m; j++){
while(r >= l && val[id(i,a[r])] <= val[id(i,j)]) r--;
a[++r] = j;
while(r >= l && a[l] <= j-p) l++;
mx[id(i,j)] = val[id(i,a[l])];
}
}
LL ans = INF;
for(int j = p-; j < m; j++){
int l = , r = -;
for(int i = ; i < n; i++){
while(r >= l && mx[id(a[r],j)] <= mx[id(i,j)]) r--;
a[++r] = i;
while(r >= l && a[l] <= i-q) l++;
if(i >= q-) ans = min(ans, mx[id(a[l],j)]);
}
}
printf("%lld\n",1ll*ans*(p+)*(q+));
return ;
}

最新文章

  1. WCF学习之旅—第三个示例之五(三十一)
  2. git管理测试生产环境代码
  3. Protocol Buffer技术详解(语言规范)
  4. POJ 1743 (后缀数组 二分) Musical Theme
  5. STUN/TURN/ICE协议在P2P SIP中的应用(二)
  6. [Redux] Adding React Router to the Project
  7. win7下自写驱动导致开机蓝屏调试过程
  8. JQuery 在$(window).load() 事件中 不运行 $(window).resize()
  9. MVC 接受Flash上传图片
  10. MySQL 基础知识梳理学习(四)----GTID
  11. 【Linux】awk指令
  12. Semaphore实现的生产者消费者程序
  13. 2.12 C++ explicit关键字详解
  14. ATM自动取款机程序感想
  15. Unity3D Shader描边效果
  16. phpStudy2——PHP脚本访问MySql数据库
  17. Ubuntu 12.04下LAMP环境搭建实录
  18. 用 Apache 发布 ASP.NET 网站
  19. 把lighttpd配置为系统服务
  20. array_diff使用注意

热门文章

  1. isMemberOfClass、isKindOfClass原理分析
  2. 的Blog
  3. 让 CXK 来教你实现游戏中的帧动画(上)
  4. S3 介绍
  5. xml的四种解析方式(转载)
  6. java文字转语音播报功能的实现方法
  7. java随笔之接口
  8. C语言数组排序——冒泡排序、选择排序、插入排序
  9. http测试工具
  10. 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践