[NFLS 1451/4] 大庆 题解

大意

给定一个 n×mn \times m 的方格, 每格中有一个数字, 设两个方格是 联通的 , 仅当两个方格相邻且数字相同 .

qq 个询问, 每次给定 ll, rr, 求从第 ll 列至第 rr 列中联通块的个数 .

数据范围

# % nn mm qq
1 1515 % 2\le 2 106\le 10^6 1.3×106\le 1.3 \times 10^6
2 7575 % 10\le 10 105\le 10^5 105\le 10^5
3 1010 % =1000= 1000 100\le 100 106\le 10^6

题解

这道题要分成 3 个部分, 对应上表中的三个数据范围.

#1

n2,m106,q1.3×106n \le 2, m \le 10^6, q \le 1.3 \times 10^6

可以发现, n2n \le 2, 同时 m,qm, q 很大, 考虑用前缀和解决.

sis_i 为前 i 列的联通块个数.

n=1n = 1 时:

si=si1+[aiai1]s_i = s_{i-1} + [a_i \not= a_{i - 1}]

n=2n = 2 时:

si=si1+[a1,ia1,i1]+[a2,ia2,i1][a1,i=a2,ia1,ia1,i1a2,ia2,i1]s_i = s_{i-1} + [a_{1, i} \not= a_{1, i-1}] + [a_{2, i} \not= a_{2, i-1}] - [a_{1, i} = a_{2, i} \wedge a_{1, i} \not= a_{1, i-1} \wedge a_{2, i} \not= a_{2, i-1}]

1

查询时, 同样解决.

n=1n = 1 时:

srsl1+[alal1]s_r - s_{l-1} + [a_l \not= a_{l - 1}]

n=2n = 2 时:

srsl1+[a1,l=a1,l1]+[a2,l=a2,l1][a1,l=a1,l1a2,l=a2,l1a1,l=a2,l]s_r - s_{l-1} + [a_{1, l} = a_{1, l-1}] + [a_{2, l} = a_{2, l-1}] - [a_{1, l} = a_{1, l-1} \wedge a_{2, l} = a_{2, l-1} \wedge a_{1, l} = a_{2, l}]

2

#2

线段树.

id(i,j)=(i1)m+jid(i, j) = (i - 1) \cdot m + j

每个节点存储 l,r,cntl, r, cnt, 分别代表该区间左端和右端的编号 (编号相同就代表数字相同, 反之不一定) , 和联通块个数.

先考虑每一列:

li,j=li1,j,i2ai,j=ai1,jli,j=id(i,j),otherwisel_{i, j} = l_{i - 1, j}, i \ge 2 \wedge a_{i, j} = a{i - 1, j} \newline \newline l_{i, j} = id(i, j), otherwise

3

然后考虑合并

首先 cntcnt(ls)+cnt(rs)cnt \leftarrow cnt(ls) + cnt(rs).

对于中间的两列, 即 ls.rrs.l, 若相同, 则用 dsu 加入同一个集合, 并 cntcnt1cnt \leftarrow cnt-1.

然后对于左右两列, ll(ls)l \leftarrow l(ls), rr(rs)r \leftarrow r(rs), 并要在 dsu 中查询.

合并完将 dsu 恢复.

4

#3

仿照 #2 的情况, 独立处理每一列, 然后合并时, 若两侧相同且不在同一个集合内, 就合并, cntcnt1cnt \leftarrow cnt - 1.

5