Gravatar
梦那边的美好TT
积分:745
提交:97 / 251

先创建一个 $map$,使 $m[队列元素]=$队列编号,这样后面好查找元素的组别;

再创建一个队列 $q[301]$,$q[i]$ 表示队列编号为 $i$ 的排队情况。$q[0]$ 表示小组的排序;

队列输入不用多说,只需要注意一个新小组的人入队要给新小组排上队;

队列输出时查看 $q[0]$ 队头,看到小组编号后查该小组的队头,再输出,注意小组的人全部出队后要把空小组删掉。


题目717  [SDOI 2007] 小组队列 AAAAAAAAAA      3      评论
2025-10-29 12:55:32    
Gravatar
梦那边的美好TT
积分:745
提交:97 / 251

【题解】

        算法一:

       思路:动态规划,$dp[i]$ 是前 $i$ 个元素的有效划分方案数,则 $f[0]=1$(空数组有 $1$ 种划分方式),$f[i]$ 为所有满足 $[j+1,i]$ 是好数组的 $f[j]$ 的和。

       时间复杂度:$O(n^2)$,即 $5000*5000=2.5*10^7$,期望 $15$ 分。

       瓶颈:不能快速判断数组是否是好数组,不能快速累加 $f[j]$;

        算法二:

       思路:有几处优化;

           $1$.对每个元素 $a[i]$,计算 $pre[i]$(上一次出现位置)和 $nxt[i]$(下一次出现位置),所以可以由好数组的性质“对于子数组内的重元素 $a[i]$,其前后出现位置必须在子数组外(否则会影响交替性)”优化判断好数组的条件;

           $2$.若 $j$ 在 $[L..R]$ 内时 $[j+1..i]$ 是好数组,则 $f[i]$ 需要累加 $f[L]+f[L+1]+...+f[R]$,所以用双线段树。好数组有两种起始类型(轻元素开始或重元素开始),需分别维护。因此使用两个线段树 $seg[0]$ 和 $seg[1]$,分别对应两种起始类型,每个线段树节点存储“区间内最大有效长度”和“对应方案数总和”支持区间增减(通过延迟标记)和单点更新;

            $3$.预先生成“区间更新事件”:当遍历到位置 $i$ 时,哪些 $j$ 的范围会因 $a[i]$ 的加入而成为有效划分点,事件按生效位置排序,遍历数组时依次触发,动态更新线段树,确保查询到的 $f[j]$ 都是有效的。

           同样方式计算 $f[i]$,最终需减去重复计算的 $f[i-1]$,对 $1000003$ 取余后输出。

       时间复杂度:$O(n*logn)$,即 $5*10^5*log5*10^5≈10^7$,轻松过 $4$ 秒时限;

       期望得分:$100$;


题目4184  轻重数字 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     4      评论
2025-10-29 12:53:24    
Gravatar
淮淮清子
积分:1042
提交:140 / 265

[CCO 2024] Heavy Light Decomposition


前置知识


分块,DP


简要题意


定义“好的数组”为一个数组内交替出现“轻元素”和“重元素”,轻元素即其在这个数组内是唯一的,重元素即其在数组内出现多次。

有 $n$ 个正整数 $a_i$,求其有多少种划分方案能使划分后的子数组均为好的数组。


分析样例


我们首先要搞懂一个东西,就是划分后好的数组,是指这个子数组是好的,在这个子数组内的轻重元素与原数组并没有关系,每个子数组是互相独立的。


对于样例一,其划分方案如下:


- $[1], [2], [3], [2], [3]$

- $[1], [2, 3, 2], [3]$

- $[1], [2], [3, 2, 3]$

- $[1, 2, 3, 2], [3]$


对于样例二,其划分方案如下:

- $[1], [2], [1], [3], [1]$

- $[1, 2, 1], [3], [1]$

- $[1, 2, 1, 3], [1]$

- $[1], [2], [1, 3, 1]$

- $[1], [2, 1, 3, 1]$

- $[1, 2, 1, 3, 1]$


不明白的建议手推一下。


思路分析


考虑转移


我们定义 $dp[i]$ 为前 $i$ 个元素的合法划分的方案数。


那么,转移方程很显然:$dp[i] = \sum dp[j]$,其中 $j < i$ 且 子数组 $[j + 1, i]$ 是好数组。


实际上含义就是在 $j$ 处划分,新增一个子数组 $[j + 1, i]$,方案累加前 $j$ 个元素的方案数。


考虑好数组的约束


如果 $[j + 1, i]$ 为好的数组,那么需要满足:


1. 类型交替:即数组内的元素轻重交替。

2. 奇偶性约束:如果重元素第一次出现在奇数位,那么奇数位全是重元素,反之。


因此我们如果直接枚举所有的 $j$ 去验证 $[j + 1, i]$ 是否为好数组,时间复杂度为 $O(n ^ 2)$。


考虑优化


对于当前的位置 $i$,我们设其元素大小为 $v$,用 $odd[v]$ 和 $even[v]$ 来记录 $v$ 在奇数和偶数位最近的出现位置,这样的话可以确定 $j$ 的下界。


为了保证子数组 $[j + 1, i]$ 满足类型交替,需要避免 $v$ 元素在数组内出现奇偶性冲突,那么若 $j + 1 < \min(odd[v], even[v])$ 的话,则会使其冲突。


因此我们使 $minL$ 取所有元素 $min(odd[v], even[v]) + 1$ 的最大值,因此 $j > minL - 1$。


然后是最重要的分块,我们将原数组分块,每个块维护两个核心内容,$sum[k][b]$ 表示 $b$ 块满足在奇偶性 $k$ 下的合法的 $dp[j]$ 之和,$kpos[k][b]$ 是在 $k$ 的奇偶性下块 $b$ 是否满足。另外,为了维护分块时的单个元素, 我们维护 $pos[k][i]$ 是单个位置的 $i$ 是否满足奇偶性 $k$。


当我们查询 $[l, r]$ 内符合条件的 $dp[j]$ 之和时,对于整块,只需要判断 $kpos$ 是否有效,然后累加 $sum$ 即可,对于单个的块边缘的元素,则需要满足 $kpos$ 和 $pos$,有效则累加 $dp[j]$。


在区间更新时,只需要标记区间有效和无效,在完整的块上更新 $kpos$,零散的元素更新 $pos$ 和 $sum$。


时间复杂度


分块的单次查询和更新的时间复杂度为 $O(\sqrt{n})$,时间复杂度为 $O(n \sqrt n)$。


简单卡常即可,最慢的点才两秒出头,对于四秒的时间限制完全够用。


题目4184  轻重数字      4      2 条 评论
2025-10-28 21:45:35    
Gravatar
梦那边的美好ET
积分:7028
提交:1292 / 2729


题目4076  小b爱旅行      4      评论
2025-10-24 11:19:14    
Gravatar
梦那边的美好ET
积分:7028
提交:1292 / 2729


题目4077  小b爱取模      3      评论
2025-10-24 11:18:43    
Gravatar
梦那边的美好ET
积分:7028
提交:1292 / 2729

Subtask1: n,m≤100

注意到我们可以枚举每一对 (E,S) 并判断 Bob 是否必胜,最后将必胜的方案数除以 nm 就是答案。

判断是否必胜我们直接将边 E 删去并从起点 S 开始搜索即可,时间复杂度 O(n2m)。期望得分 30pts。

Subtask2: w=1

除非 S 是叶子且 E 恰好是 S 的唯一出边,Bob 都是必胜的。统计是简单的,不再赘述。

Subtask3: n,m≤5000

考虑从边双连通分量入手,我们枚举 E。

若 E 不是割边,那么删除 E 不会影响 S 所能到达的点/边集。只要原图中还存在边权与 E 相等的边,那 Bob 就是必胜的,贡献为 n。

若 E 是割边,那么删除 E 会将边双树分为两个连通块,而 S 只能遍历其所处的连通块,所以 Bob 必胜等价于该连通块中有边权与 E 相等的边。直接遍历两个连通块来判断即可。

割边的数量可以达到与 n 同阶,故时间复杂度为 O(nm)。期望得分 60pts。

Subtask3: n,m≤106

考虑优化 E 是割边时的判断过程。注意到一个连通块必定是边双树中的一颗子树或者全树扣掉一颗子树,而后者可以直接用全局减去该子树得到。于是问题等价于求一棵子树中边权与根的父边相等的边的数量。

这个问题的做法非常多,容易 O(n) 实现,期望得分 100pts。


题目3920  编辑题目      4      1 条 评论
2025-10-24 11:15:02