#P12502. 「CEOI2025」BoardOina 游戏

「CEOI2025」BoardOina 游戏

注意事项

请在提交源代码前添加 #include "boardgames.h"

题目描述

每年,克卢日-纳波卡都会举办一场大型桌游博览会,展示众多新游戏。今年的主要亮点是一款名为 BoardOina 的游戏。

nn 名玩家排成一队,等待尝试这款游戏。玩家按照队列顺序编号为 00n1n-1。玩家 00 在队列最前面,玩家 n1n-1 在队列最后面。

队列中有 mm不同友谊关系,涉及 mm 对玩家。具体来说,对于从 00m1m-1 的每个 ii,玩家 x[i]x[i] 和玩家 y[i]y[i] 是朋友,其中 0x[i]<y[i]<n0 \leq x[i] < y[i] < n。友谊关系是对称的。

考虑队列中从玩家 ss 开始的 kk 个连续玩家序列(对于任意 sskk,满足 0s<n0 \leq s < n1kns1 \leq k \leq n-s)。如果对于该序列中的任意两个玩家,他们通过该朋友组内的友谊关系序列相连,则该玩家序列形成一个大小为 kk朋友组。具体来说,玩家 s,s+1,,s+k1s, s+1, \ldots, s+k-1 形成一个大小为 kk 的朋友组,如果对于每个 uuvv(满足 su<v<s+ks \leq u < v < s+k),存在一个玩家序列 p[0],,p[l1]p[0], \ldots, p[l-1],满足:

  • l2l \geq 2
  • 对于每个 jj(从 00l1l-1),sp[j]<s+ks \leq p[j] < s+k
  • p[0]=up[0] = up[l1]=vp[l-1] = v
  • 对于每个 jj(从 00l2l-2),玩家 p[j]p[j]p[j+1]p[j+1] 是朋友。

注意,当 k=1k = 1 时,玩家 ss 单独形成一个大小为 11 的朋友组。

BoardOina 可以由任意数量的玩家游玩。然而,为了使游戏更成功,组织者只允许朋友组参与游戏。

一次只能有一个组玩游戏。对于每场游戏,从队列最前面的玩家开始形成一个朋友组,并开始玩游戏。该朋友组中的玩家从队列中移除。重复此过程,直到队列变空为止。形式上,我们说队列可以被分成 gg 个朋友组,如果存在一个组大小数组 K=[K[0],K[1],,K[g1]]K = [K[0], K[1], \ldots, K[g-1]],满足以下条件:

  • g>0g > 0 且对于每个 jj (0j<g)(0 \leq j < g)K[j]>0K[j] > 0
  • K[0]+K[1]++K[g1]=nK[0] + K[1] + \ldots + K[g-1] = n
  • 对于每个 jj(从 00g1g-1),玩家 s[j],s[j]+1,,s[j]+K[j]1s[j], s[j]+1, \ldots, s[j]+K[j]-1 形成一个大小为 K[j]K[j] 的朋友组,其中 s[0]=0s[0]=0,否则 s[j]=K[0]+K[1]++K[j1]s[j]=K[0]+K[1]+\ldots+K[j-1]

组织者希望最小化玩游戏的朋友组数量。也就是说,他们希望将队列分成 gg 个朋友组,使得无法将队列分成 g1g-1 个(或更少)朋友组。

你的任务是找到一个将队列分成最少朋友组的分组方式,并报告组大小数组。

实现细节

你应该实现以下程序:

std::vector<int> partition_players(int n, int m, std::vector<int> X, std::vector<int> Y)
  • nn:队列中的玩家数量。
  • mm:友谊关系的数量。
  • XX, YY:长度为 mm 的数组,描述友谊关系。
  • 该程序应返回一个组大小数组,表示将玩家队列分成最少数量的朋友组。
  • 对于每个测试点,该程序只被调用一次。

示例评测程序

示例评测程序读取以下格式的输入:

  • 11 行:n mn\ m
  • 2+i2 + i (0i<m)(0 \leq i < m) 行:x[i] y[i]x[i]\ y[i]

partition_players 返回的数组元素为 K[0],K[1],,K[g1]K[0], K[1], \ldots, K[g-1],其中 gg 为非负数。示例评测程序的输出格式如下:

  • 11 行:gg
  • 22 行:K[0] K[1]  K[g1]K[0]\ K[1]\ \ldots\ K[g-1]

样例 1

考虑以下调用:

partition_players(5, 3, {0, 1, 3}, {1, 4, 4})

在这个示例中,玩家 0011、玩家 1144、以及玩家 3344 是朋友。

玩家 22 在队列中没有朋友,因此必须单独形成一个大小为 11 的朋友组,这意味着最少朋友组数量为 g=3g = 3。另一方面,玩家 0011,以及玩家 3344 可以形成大小为 22 的朋友组。

因此,队列可以被分成 33 个朋友组,大小分别为 221122,所以程序可以返回 [2, 1, 2]

样例 2

考虑以下调用:

partition_players(7, 6, {0, 4, 2, 1, 2, 3}, {1, 5, 4, 5, 5, 6})

在这个示例中,玩家 0011、玩家 4455、玩家 2244、玩家 1155、玩家 2255 以及玩家 3366 是朋友。

玩家 33 的唯一朋友是玩家 66,因此任何包含玩家 33 的朋友组要么是:

  • 大小为 11 的朋友组,仅包含玩家 33
  • 包含玩家 33 和玩家 66 的朋友组。

在第二种情况下,朋友组还必须包含玩家 4455。这是不可能的,因为玩家 66 的唯一朋友是玩家 33,所以玩家 33 无法通过友谊关系序列与玩家 4455 相连。

因此,玩家 33 必须被放入一个大小为 11 的朋友组。类似地,玩家 66 也必须被放入一个大小为 11 的朋友组,因此分组中的朋友组数量至少为 44

玩家 001122 无法形成一个大小为 33 的朋友组,因为玩家 0011 无法通过组内的友谊关系序列与玩家 22 相连。如果组内有玩家 55,情况可能不同,但由于玩家 3344 肯定会在不同的组中,这种情况不会发生。也就是说,分组中的朋友组数量至少为 55

另一方面,玩家 0011,以及玩家 4455 可以形成两个大小为 22 的朋友组。

因此,队列可以被分成 55 个朋友组,大小分别为 2211112211。程序可以返回 [2, 1, 1, 2, 1]

数据范围与提示

对于所有输入数据,满足:

  • 2n1000002 \leq n \leq 100\,000
  • 0m2000000 \leq m \leq 200\,000
  • 对于每个 ii (0i<m)(0 \leq i < m)0x[i]<y[i]<n0 \leq x[i] < y[i] < n
  • 友谊关系是不同的。换句话说,对于每个 iijj (0i<j<m)(0 \leq i < j < m)x[i]x[j]x[i] \neq x[j]y[i]y[j]y[i] \neq y[j]
  • 如果存在多个具有最小组数量的答案,你可以返回任意一个合法的答案。

详细子任务附加限制及分值如下表所示。

子任务 分值 附加限制
11 55 对于每个 ii(从 00m1m-1),y[i]=x[i]+1y[i] = x[i] + 1
22 77 对于每个 ii(从 00m1m-1),y[i]x[i]+2y[i] \leq x[i] + 2
33 66 n300n \leq 300m600m \leq 600
44 1515 n2000n \leq 2000m4000m \leq 4000
55 3434 没有循环的友谊关系。即,对于任意不同的玩家序列 p[0],p[1],,p[l1]p[0], p[1], \ldots, p[l-1] (l3)(l \geq 3),如果对于每个 0j<l10 \leq j < l-1,玩家 p[j]p[j]p[j+1]p[j+1] 是朋友,则玩家 p[0]p[0]p[l1]p[l-1] 不是朋友。
66 3333 无附加限制