T1

100%

题目已经给出第 ii 个测试点能够通过的条件:

nixmi=1.n_i\le x\quad\text{或}\quad m_i=1.

用一个变量记录满足条件的测试点个数。依次读入 kk 个测试点,若上述条件成立就把答案加一。最容易写错的是把“或”误写成“且”。

时间复杂度为 O(k)O(k)

T2

100%

rir_i 为在第 ii 行游动的小鱼数量,cic_i 为在第 ii 列游动的小鱼数量。多条鱼可能位于同一行或同一列,因此这里记录的是数量而不是是否出现。

左上角为 (x,y)(x,y) 的区域能吃到 R(x)+C(y)R(x)+C(y) 条鱼,其中

$$R(x)=r_x+r_{x+1}+r_{x+2}, C(y)=c_y+c_{y+1}+c_{y+2}$$

此时如果我们枚举 x,yx,y 的值后,计算 R(x)+C(y)R(x) + C(y) 也可通过,时间复杂度为 O(n2+m)O(n^2 + m),以下介绍一种 O(n+m)O(n+ m) 的做法。

R(x)R(x) 只由 xx 决定,C(y)C(y) 只由 yy 决定,所以可以分别求两者的最大值。若 x0x_0 使 RR 最大、y0y_0 使 CC 最大,那么对任意 (x,y)(x,y) 都有

R(x)+C(y)R(x0)+C(y0),R(x)+C(y)\le R(x_0)+C(y_0),

(x0,y0)(x_0,y_0) 是全局最优位置。

从小到大枚举 xxyy,并且只在窗口和严格变大时更新。这样出现并列最优时,会自然保留最小的 xxyy,满足题目的要求。

读入并统计小鱼需要 O(m)O(m),枚举所有三行、三列窗口需要 O(n)O(n)。总时间复杂度为 O(n+m)O(n+m)

T3

100%

假设调整后所有元素都等于 vv

对于每个奇数下标 ii,有

ai+x=v.a_i+x=v.

所有奇数位置加上的数相同,因此它们在调整前就必须全部相等。记这个公共值为 OO

同理,所有偶数位置在调整前也必须全部相等,记公共值为 EE。当奇数、偶数位置都存在时,还需要

O+x=Ex,O+x=E-x,

2x=EO.2x=E-O.

于是合法解存在的条件为:

  1. 所有奇数下标的值相同;
  2. 所有偶数下标的值相同;
  3. EOE\ge O
  4. EOE-O 是偶数。

条件成立时,唯一可能的答案是

x=EO2.x=\frac{E-O}{2}.

该值既然唯一,自然也是最小合法值。

n=1n=1 时没有偶数位置。单个元素总是已经“全部相等”,最小答案为 00

时间复杂度为 O(n)O(\sum n)

T4

30%

n1000n\le1000,可以枚举每个 x[1,n]x\in[1,n],再逐对检查

(aix)=(ani+1x).(a_i\le x)=(a_{n-i+1}\le x).

若所有对称位置都满足等式,则对应的二进制数组是回文数组。

共有 nn 个阈值,每个阈值检查 O(n)O(n) 个位置,时间复杂度为 O(n2)O(n^2),空间复杂度为 O(n)O(n)

100%

本题有 22 种实现方式,但思路上是类似的。

解法 1

子任务 1 的瓶颈是:阈值从 x1x-1 变成 xx 时,绝大多数位置的 bib_i 没有变化,却仍然重新扫描了整个数组。

可以发现当阈值从 x1x - 1 变成 xx 时,只有满足 ai=xa_i=x 的位置会从 11 变为 00,其余位置保持不变。

所以考虑记录每个值 xx 在数组中的全部出现位置,以及维护 bibni+1b_i \not= b_{n -i +1} 的对数。

xx 变化时,我们可以直接动态更新 bb 数组的值,从而维护出 bibni+1b_i \not= b_{n -i +1} 的对数,当bibni+1b_i \not= b_{n -i +1} 的对数为 00 时,那么 xx 就是符合条件的,将其记录到答案中即可。

时间复杂度 O(n)O(n)

解法 2

考虑 aa 的一对值 (ai,ani+1)=(u,v)(a_i,a_{n -i + 1}) = (u , v),不妨设 u<vu<v。根据二进制数组的定义:

  • x<ux<u 时,两边都大于 xx,二进制值同为 11
  • ux<vu\le x<v 时,只有 uxu\le x,两边的二进制值不同;
  • xvx\ge v 时,两边都不大于 xx,二进制值同为 00

因此,这一对位置恰好使阈值区间

[u,v1][u,v-1]

非法。若 u=vu=v,它们对任意阈值都相等,不产生非法区间。

对每一对对称位置令

l=min(ai,ani+1),r=max(ai,ani+1)l=\min(a_i,a_{n-i+1}),r=\max(a_i,a_{n-i+1})

l<rl<r 时,使用差分数组把区间 [l,r1][l,r-1] 加一。

最后求差分数组的前缀和。阈值 xx 的覆盖次数就是在该阈值下失配的对称位置对数:覆盖次数为 00 当且仅当数组 bb 是回文数组。

时间复杂度为 O(n)O(n),空间复杂度为 O(n)O(n)

T5

100%

tt 秒在线的服务器恰好是满足 aita_i\ge t 的位置。设这些位置形成的极大连续段长度依次为

b1,b2,,bk,b_1,b_2,\ldots,b_k,

则这一秒完成的任务数为

F(t)=j=1kpbj.F(t)=\sum_{j=1}^{k}p_{b_j}.

答案就是

t1F(t).\sum_{t\ge1}F(t).

随着 tt 变化,在线位置集合只会在某个 aia_i 处发生改变。因此,无须逐秒计算;只要按 aia_i 排序,在相邻事件值之间一次性累加贡献即可。

根据处理方式不同,有两种做法。

解法 1

将所有位置按 aia_i 从大到小排序。开始时所有位置都未激活,然后依次处理每个不同的在线时长 vv,一次性激活所有满足 ai=va_i=v 的位置。

设当前所有连续段的单秒贡献之和为 SS。激活位置 ii 时,它先单独形成长度为 11 的连续段,因此令

S+=p1.S\mathrel{+}=p_1.

随后检查 i1i-1i+1i+1。若相邻位置已经激活,就用并查集合并两个连续段。若合并前两段长度分别为 x,yx,y,则更新S=px+py,S+=px+yS-=p_x+p_y,S+=p_{x+y}

设处理完事件值 vv 后,下一个更小的事件值为 ww;若不存在则令 w=0w=0。此时已激活的位置恰好满足 aiva_i\ge v。对于所有整数秒 tt 满足

w<tvw<t\le v

在线位置集合都与当前状态相同,所以答案增加

(vw)S(v-w)S

总时间复杂度为 O(nlogn)O(n\log n)

做法 2

也可以反过来维护:一开始把所有位置看作在线,令当前单秒贡献

S=pnS=p_n

将位置按 aia_i 从小到大排序并依次删除。用 set 维护已经删除的位置。

设上一个处理到的在线时长为 lastlast。准备删除位置 ii 时,令 v=aiv=a_i。在删除之前,先累加 (vlast)S(v-last)S(表示上一个时间点到当前时间点的答案),再令 last=vlast=v

接着在 set 中找到 ii 左右两侧最近的已删除位置 l,rl,r。删除前,区间

[l+1,r1][l+1,r-1]

是一段长度为 rl1r-l-1 的完整连续段。删除 ii 后,它被拆成长度分别为 il1,ri1i-l-1, r-i-1 的两段,因此维护对应的 SS 的值即可。

最后把 ii 插入 set 即可。为了能在 set 中找到 ii 左右两侧最近的已删除位置,可以先在 set 中插入一个 n+1n + 100 作为哨兵。

时间复杂度 O(nlogn)O(n \log n)

T6

30%

特殊性质 A 保证字符串中所有字符相同。于是任意非空集合 AA 都满足

smin(A)=smax(A)s_{\min(A)}=s_{\max(A)}

问题变成求 nn 个有标号元素的集合划分数,即 Bell 数。具体求法可见 这里

时间复杂度 O(n2)O(n^2) 即可通过。

100%

对于划分中的一个集合 AA

  • A=1|A|=1,它是单元素集合,一定合法;
  • A2|A|\ge2,把 min(A)\min(A) 视为集合的起点,max(A)\max(A) 视为终点,其余元素视为内部元素。

按下标从小到大扫描时,一个非单元素集合会先在最小下标处被创建,接收若干内部元素,最后在最大下标处结束。合法条件只要求起点字符与终点字符相同。

因此,只需记录尚未结束的集合中,有多少个起点字符为 0,有多少个起点字符为 1。利用这个性质,我们考虑动态规划。

f[i][x][y]f[i][x][y] 表示已经处理完前 ii 个下标,其中有 xx 个起点字符为 00 的开放集合、yy 个起点字符为 11 的开放集合时的方案数。已经处理的每个下标都恰好被分配到一个集合;已经关闭的集合不再需要记录。

初始时尚未处理任何下标,也没有开放集合,故f[0][0][0]=1f[0][0][0]=1。其余状态均为 00。处理完全部下标后不能留下开放集合,因此最终答案为 f[n][0][0]f[n][0][0]

考虑转移。考虑处理下标 i+1i+1,设当前字符为 c=si+1c=s_{i+1}。这个下标有四种用途:

  1. 单独构成一个单元素集合,开放集合数量不变,只有 11 种选择;
  2. 加入某个开放集合并作为内部元素,可以从 x+yx+y 个开放集合中选择一个,开放集合数量不变;
  3. 成为一个新集合的起点,新增一个起点字符为 cc 的开放集合;
  4. 成为某个开放集合的终点,只能选择起点字符同样为 cc 的开放集合。

c=0c=0 为例,四种用途的转移分别为:

  1. f[i][x][y]f[i+1][x][y]f[i][x][y]\to f[i+1][x][y]
  2. (x+y)f[i][x][y]f[i+1][x][y](x+y)f[i][x][y]\to f[i+1][x][y]
  3. f[i][x][y]f[i+1][x+1][y]f[i][x][y] \to f[i+1][x+1][y]
  4. xf[i][x][y]f[i+1][x1][y]xf[i][x][y]\to f[i+1][x-1][y]

所有下标越界的状态都视为 00。上述四种情况恰好覆盖了当前下标在所属集合中的所有可能角色,因此不会重复或遗漏任何划分。

总时间复杂度为 O(n3)O(n^3)。使用滚动数组后空间复杂度为 O(n2)O(n^2)

0 comments

No comments so far...