一、题意

给定一个高度为$n$,宽度为$m$的字母矩形(有大写和小写字母,共$52$种),问里面有多少个子矩形是“数独矩形”。数独矩形是指,该矩形内每一行内元素都不相同,每一列内元素也不相同。

二、思路

对于每一个点$(i, j)$,预处理出$R[i][j]$,表示在第$i$行从第$j$列开始,往右一直到$R[i][j]$位置,这一段内所有元素都不相同。同理,再预处理出$D[i][j]$,表示在第$j$列从第$i$行开始,往下一直到$D[i][j]$位置,这一段内所有元素都不相同。显然,无论是往右还是往下这样的一段,长度都不会超过$52$。形式表示就是,$max\{R[i][j]\}=52(1 \le i \le n,1 \le j \le m)$,$max\{D[i][j]\}=52(1 \le i \le n,1 \le j \le m)$。

所以这部分的ACM版时间复杂度为$O(52*n*m)$。

接下来,枚举每一个点$(i, j)$,统计以点$(i, j)$作为左上角的数独矩形的个数。记住,一定要以点$(i, j)$作为左上角。

示意图如下,其中,绿色竖条代表$D[i][k](j \le k \le R[i][j])$,黄色横点条代表$R[k][j](i \le k \le D[i][j])$。

从$i$开始枚举每一行(显然只需要枚举到$D[i][j]$即可,最多循环$52$次),从第$i$行开始,记录一个右边界minr,表示:所有以$(i, j)$为左上角的行数为$k-i+1$的数独矩形最右边可到达的边界。假设当前在第$k$行,当前的右边界为$minr$,那么,所有以$(i, j)$为左上角的行数为$k-i+1$的数独矩形的个数为$minr-j+1$。举个例子,对于上图中,假设左上角坐标为$(i, j)$,当前枚举的行号$k=i$,则$minr=j+7$,这一行中数独矩形的个数为$minr-j+1=8$个,也就是$[(i, j)], [(i, j), (i, j+1)], [(i, j), (i, j+1), (i, j+2)], \dots, [(i, j), (i, j+1), (i, j+2), \dots, (i, minr)]$。

当枚举的行号$k=i+1$时,此时$minr=j+5=R[k][j]$,行数为两行(第$i$行和第$i+1$行)中数独矩形的个数为$minr-j+1=6$个。也就是:

后面的同理。然后,要注意的是,当$min\{D[i][k]\}(j \le k \le minr) < k$($j$~$minr$之间的最短的绿色竖条到不了$k$)或者$R[k][j] < minr$(第$k$行的黄色横点条到不了$minr$)时,说明以点$(i, j)$为左上角的高度为$k-i+1$的数独矩形的个数没有$minr-j+1$个,需要减小$minr$。

总的ACM版时间复杂度为$O(52*n*m)$。

三、代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1010
char s[MAXN][MAXN];
int n, m, R[MAXN][MAXN], D[MAXN][MAXN];
int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output2.txt", "w", stdout);
    scanf("%d%d", &n, &m);
    ; i <= n; ++i) {
        scanf();
        ; j <= m; ++j) {
            ;
            ;
        }
    }
    ; i <= n; ++i) {
        ; j <= m; ++j) {
            , m), k = j;
            ;
            for(k = j; k <= r; ++k) {
                ))b |= 1LL << s[i][k];
                else {
                    R[i][j] = k - ;
                    break;
                }
            } )R[i][j] = k - ;
        }
    }
    ; j <= m; ++j) {
        ; i <= n; ++i) {
            , n), k = i;
            ;
            for(k = i; k <= r; ++k) {
                ))b |= 1LL << s[k][j];
                else {
                    D[i][j] = k - ;
                    break;
                }
            } )D[i][j] = k - ;
        }
    }
    ;
    ];
    ; i <= n; ++i) {
        ; j <= m; ++j) {
            , min(R[i][j], m)), k = j, minr;
            mind[] = D[i][j];
            ; k <= r; ++k) {
                mind[k - j] = min(mind[k - j - ], D[i][k]);
            }
            r = min(i + , min(D[i][j], n)), k = i, minr = R[i][j];
            for(k = i; k <= r; ++k) {
                while(minr > j && (R[k][j] < minr || mind[minr - j] < k))minr--;
                ans += minr - j + ;
            }
        }
    }
    cout << ans << '\n';
    ;
}

牛客网暑期ACM多校训练营(第七场)J题(Sudoku Subrectangles)题解的更多相关文章

  1. 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)

    题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...

  2. 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

    牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...

  3. 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学

    牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...

  4. 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)

    2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...

  5. 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)

    链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  6. 牛客网暑期ACM多校训练营(第九场) A题 FWT

    链接:https://www.nowcoder.com/acm/contest/147/A来源:牛客网 Niuniu has recently learned how to use Gaussian ...

  7. 牛客网暑期ACM多校训练营(第九场)D

    链接:https://www.nowcoder.com/acm/contest/147/D来源:牛客网 Niuniu likes traveling. Now he will travel on a ...

  8. 牛客网暑期ACM多校训练营(第二场)B discount

    链接:https://www.nowcoder.com/acm/contest/140/B来源:牛客网 题目描述 White Rabbit wants to buy some drinks from ...

  9. 2018牛客网暑期ACM多校训练营(第一场)D图同构,J

    链接:https://www.nowcoder.com/acm/contest/139/D来源:牛客网 同构图:假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所 ...

  10. 牛客网暑期ACM多校训练营(第二场) I Car 思维

    链接:https://www.nowcoder.com/acm/contest/140/I来源:牛客网 White Cloud has a square of n*n from (1,1) to (n ...

随机推荐

  1. 组件的 keep-alive 简介

    本篇文章,我们来讲一下keep-alive的实现.  更容易看懂 Vue中,有三个内置的抽象组件,分别是keep-alive.transition和transition-group, 它们都有一个共同 ...

  2. 解决 Error: could not open `C:\Program Files\Java\jre7\lib\i386\jvm.cfg'

    解决 Error: could not open `C:\Program Files\Java\jre7\lib\i386\jvm.cfg' 重装JDK后,因为没有装在以前的目录,运行java命令后报 ...

  3. 15款Cocos2d-x游戏源码

    (1)用cocos2d-x开发的中国象棋游戏源码 使用Cocos2d-X2.2.3开发的一款中国象棋游戏,游戏中可以实现.新局面.悔棋.游戏音乐.胜利后会显示游戏结果. 源码下载:http://www ...

  4. HAWQ + MADlib 玩转数据挖掘之(六)——主成分分析与主成分投影

    一.主成分分析(Principal Component Analysis,PCA)简介 在数据挖掘中经常会遇到多个变量的问题,而且在多数情况下,多个变量之间常常存在一定的相关性.例如,网站的" ...

  5. P1002 谁拿了最多奖学金

    P1002 谁拿了最多奖学金 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2005复赛提高组第一题 描述 某校的惯例是在每学期的期末考试之后发放奖 ...

  6. linux makefile (English)

    ############################################################################## Generic Makefile for ...

  7. Unity 3D编辑器扩展介绍、教程(二) —— 创建窗口

    Unity编辑器扩展教程(二) 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 一 Brief Introd ...

  8. ElasticSearch(九):springboot项目集成消息中间件activeMQ

    目的:为了将elasticsearch做成单独的服务,那么我们必须解耦,也就是业务逻辑和搜索模块是没有关系的,并且是异步的.那么项目之间通信,使用的选择有限,消息中间件是一个不错的选择. 消息中间件常 ...

  9. 我的第一个Mybatis程序

    第一个Mybatis程序 在JDBC小结中(可以参阅本人JDBC系列文章),介绍到了ORM,其中Mybatis就是一个不错的ORM框架 MyBatis由iBatis演化而来 iBATIS一词来源于“i ...

  10. 今天遇到的一个奇葩的NoClassFound的问题

    nohup的日志中报错 java.lang.NoClassDefFoundError: org/apache/catalina/core/ApplicationContext$DispatchData ...