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

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

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define max3(a,b,c) max(a,max(b,c))
 12 #define min3(a,b,c) min(a,min(b,c))
 13 typedef pair<int,int> pll;
 14 const int inf = 0x3f3f3f3f;
 15 const LL INF = 0x3f3f3f3f3f3f3f3f;
 16 const LL mod =  (int)1e9+7;
 17 const int N = 1e6 + 100;
 18 string s, ss;
 19 int val[N];
 20 int nx[N];
 21 int n, m;
 22 inline int id(int x, int y){
 23     return m * x + y;
 24 }
 25 int cnt[N];
 26 void get_nt(int u){
 27     nx[0] = -1;
 28     int j = 0, k = -1;
 29     while(j < m){
 30         if(k == -1 || s[id(u,j)] == s[id(u,k)]) nx[++j] = ++k;
 31         else k = nx[k];
 32     }
 33     int pos = m;
 34     while(pos != -1){
 35         cnt[m-pos]++;
 36         pos = nx[pos];
 37     }
 38 }
 39 void get_nt_(int u){
 40     nx[0] = -1;
 41     int j = 0, k = -1;
 42     while(j < n){
 43         if(k == -1 || s[id(j,u)] == s[id(k,u)]) nx[++j] = ++k;
 44         else k = nx[k];
 45     }
 46     int pos = n;
 47     while(pos != -1){
 48         cnt[n-pos]++;
 49         pos = nx[pos];
 50     }
 51 }
 52 int a[N];
 53 LL mx[N];
 54 int main(){
 55     scanf("%d%d", &n, &m);
 56     for(int i = 1; i <= n; i++){
 57         cin >> ss;
 58         s += ss;
 59     }
 60     for(int i = 0; i < n*m; i++)
 61         scanf("%d", &val[i]);
 62     int p = 1, q = 1;
 63     memset(cnt, 0, sizeof(cnt));
 64     for(int i = 0; i < n; i++)  get_nt(i);
 65     for(int i = 1; i <= m; i++){
 66         if(cnt[i] == n) {
 67             p = i;
 68             break;
 69         }
 70     }
 71     memset(cnt, 0, sizeof(cnt));
 72     for(int i = 0; i < m; i++)  get_nt_(i);
 73     for(int i = 1; i <= n; i++){
 74         if(cnt[i] == m) {
 75             q = i;
 76             break;
 77         }
 78     }
 79     /// q*p
 80     for(int i = 0; i < n; i++){
 81         int l = 0 , r = -1;
 82         for(int j = 0; j < m; j++){
 83             while(r >= l && val[id(i,a[r])] <= val[id(i,j)]) r--;
 84             a[++r] = j;
 85             while(r >= l && a[l] <= j-p) l++;
 86             mx[id(i,j)] = val[id(i,a[l])];
 87         }
 88     }
 89     LL ans = INF;
 90     for(int j = p-1; j < m; j++){
 91         int l = 0 , r = -1;
 92         for(int i = 0; i < n; i++){
 93             while(r >= l && mx[id(a[r],j)] <= mx[id(i,j)]) r--;
 94             a[++r] = i;
 95             while(r >= l && a[l] <= i-q) l++;
 96             if(i >= q-1) ans = min(ans, mx[id(a[l],j)]);
 97         }
 98     }
 99     printf("%lld\n",1ll*ans*(p+1)*(q+1));
100     return 0;
101 }

View Code

转载于:https://www.cnblogs.com/MingSD/p/9360604.html

牛客暑假多校第二场 K carpet相关推荐

  1. 2021牛客暑假多校第二场 K题—Stack (链表)

    2021牛客暑假多校第二场 K题-Stack 题意: 一个单调栈,给你第n次操作时里面数据的数量,让你给出里面塞入的会是哪些数字. 主要思想:链表模拟 (代码里面有注释) (题解一开始说的是拓扑,后来 ...

  2. 2020牛客暑假多校第二场补题

    比赛链接:link 题目 A kmp + Hash B 几何 C dfs D 签到题 F 单调区间 + gcd筛 G bitset神奇用法 H 权值线段树(动态开点/离散化) J 群论     A k ...

  3. 2021牛客暑假多校第八场 K题—Yet Another Problem About Pi

    2021牛客暑假多校第八场 K题-Yet Another Problem About Pi 题意:告诉你一个单元格的长和宽,问你走Π(3.1415926-)的长度距离最多可以走几个单元格 思路:沿着单 ...

  4. 2019牛客暑假多校7E:Find the median【线段树上二分】

    题目: 2019牛客暑期多校训练营第七场E:Find the median 题意: 给出N个操作,每次操作向数组中插入[L,R]的数字,每次操作后询问数组中的中位数 分析: 如果L,R都比较小,就可以 ...

  5. 2019牛客暑假多校训练 第四场 triples I 按位或运算

    链接:https://ac.nowcoder.com/acm/contest/884/D 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...

  6. 2018牛客暑假多校A题GPA 01分数规划

    链接:https://www.nowcoder.com/acm/contest/143/A 来源:牛客网 gpa 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语 ...

  7. 2019牛客暑假多校训练赛第七场C Governing sand(暴力)

    题目链接:https://ac.nowcoder.com/acm/contest/887/C 题意:给出n种树和n个h[i],c[i],p[i]代表每种树的高度,砍掉一棵的花费,树的个数.现在要求砍掉 ...

  8. 2021牛客暑期多校训练营2 K Stack

    题目大意: 题目告诉你利用单调栈几个点前面比它小并包含它自身的元素有多少个 让你构造一个包含1到n并每个数字只出现一次的序列 思路: 我们可以对于每个点都算出栈中元素的数量 对于没有给出的点的栈中元素 ...

  9. Average(牛客暑假训练营第四场)

    Average 链接: link. 大意: 求平均值最大的子矩阵,要求第一行长度至少为xxx,第二行长度至少为yyy. 题解:(二分+前缀和) 该问题相当于求长度至少为xxx(yyy)的最大平均值子区 ...

最新文章

  1. HALCON示例程序check_blister_mixed.hedv药品胶囊缺陷检测
  2. 近期 AI 领域,招聘招生信息汇总
  3. 算法笔记:简单的字符串模式匹配-BF算法
  4. 用 iBiu 3 秒构建出大型 Vue 项目架子
  5. 空循环和无穷循环的区别
  6. 关于mqtt+js前端中mqtt服务器关闭重连服务器后js前端接收不到消息的问题
  7. 2019版本VS 社区版本 30天试用期 过期的解决方法
  8. 我们不曾向这个世界的庸俗低头
  9. 输入法 箭头符号大全
  10. 联想服务器pe进系统还原,传授联想如何一键还原系统
  11. 密码如何改变了我的一生
  12. 幽默故事:1、小帅哥应聘;2、不交作业(木子家原创)
  13. 数据科学之 如何找到指标的最 佳分裂点的几个想法
  14. 峰哥买房用的贝壳app,他们的大数据平台如何实现的?
  15. Win10 电脑屏幕亮度随背景颜色变化而变化
  16. android连路由器 mtu,解决app无网络问题,将宽带路由器MTU从1500修改成1480
  17. 南大通用GBase XDM支持的操作平台
  18. clickhouse PARTITION操作
  19. springboot o.a.tomcat.util.scan.StandardJarScanner : Failed to scan [file:/D:/apache-maven-3.0.5
  20. 【作品分享】一次函数计算器

热门文章

  1. 才智杂志社才智杂志才智编辑部2022年第36期目录
  2. spring-data-redis 实现用户登录次数限制以及冻结时间重试机制
  3. java对象为什么要重写equals方法
  4. 160_zigbee协调器_一种判断数据包有没有拿对的方法【掐头去尾发,拿头指针、尾指针去判断】
  5. Altium Designer 10 下载和安装破解教程
  6. scratch3.0自定义logo
  7. vpa函数python_python 调用百度接口 做人脸识别
  8. HDFS删除并清空回收站
  9. 京东面试官:给我说说你简历上的订单系统是如何设计的?尽量详细点~
  10. 字符串首尾空格去除问题