昨晚打的cf,都把F切了,结果不计rating…
题目大意
给定k个n*m的由小写字母组成的矩阵(给定方式:先给定一个n *m的最初矩阵,然后k个矩阵对应5个参数a,b,c,d,e,其中(a,b)是左上角,(c,d)是右下角,然后把原矩阵的这个子矩阵的字符全部改成e)。两个矩阵的距离定义为对应每个位置字符相减之差的和。问:k个矩阵中到所有其它矩阵最小的距离和。
n,m≤1000 k≤300000
思路
n*m不大,所以可以尝试对每一位都预处理出填每个字符的答案。
首先把k个矩阵在行a,c处打插入、删除标记。由于覆盖的部分是个矩形,列对应的是一个区间。
我比赛时的naive做法
开26个线段树对应每个小写字母,然后插入、删除就是区间加减。计算每个点的答案时,先在26个线段树里单点查询,取出每种字母对应的答案(注意有些矩阵中不覆盖掉当前点,就要把原矩阵的字母算上)。然后枚举填的字母,直接计算即可。
接下来是统计答案:对填每种字母、原矩阵已经求出来每一位的答案,做一个二维前缀和,然后枚举k个矩阵,在原矩阵的答案上减去覆盖掉矩形的答案,再把填上对应字母的答案加上,就得到了该矩阵的答案了。
时间复杂度 O(26nmlogm) ,可以通过所有数据。
更快的做法
log其实可以去掉。
对于每个矩形的参数a,b,c,d,对应的字符中,在(a,b)、(c+1,d+1)处打+1标记,(c+1,b)、(a,d+1)处打-1标记。然后求前缀和。可以发现,对于任意一个矩形的前缀和,如果在矩形内部,它正好+1,否则为0。
接下来就是枚举每个位置的字母,然后二维前缀和。
时间复杂度 O(