2025.12.20 作业 - # P13339 [EGOI 2025] Gift Boxes / 礼品盒
题目描述
今年的 EGOI 在波恩举办。主办方希望为比赛中的每支队伍最多分发一个礼品盒,每支队伍的编号为 \(0\) 到 \(T-1\)。所有参赛选手排成一排,但他们的顺序是混乱的,因此同一队的成员可能不会站在一起。注意,队伍中一定至少有一支队伍在队列中有多于一名成员。队列中共有 \(N\) 个人,第 \(i\) 个人属于编号为 \(a_i\) 的队伍。问题是:每支队伍最多只能获得一个礼品盒。为了让礼品发放过程顺利进行——即使因此有些队伍无法获得礼品盒——主办方希望在发放过程中恰好暂停一次,跳过一段连续的选手,然后再继续发放。换句话说,他们会跳过一个连续区间 \([\ell, r]\) 的选手。
并不要求每支队伍都必须收到礼品盒。然而,主办方希望在不违反“每支队伍至多一个礼品盒”这一前提下,使收到礼品盒的队伍数尽量多,同时要最小化被跳过的选手数量。请帮助主办方决定在哪一段暂停以及何时继续发放礼品盒,才能使被跳过的选手尽可能少。
输入格式
输入的第一行包含两个整数 \(T\) 和 \(N\)——队伍数和队列中的选手数。
第二行包含 \(N\) 个整数 \(a_i\),第 \(i\) 个整数表示队列中第 \(i\) 个选手所属的队伍编号。保证 \(0\) 到 \(T-1\) 的每个整数至少出现一次。
输出格式
输出两个整数 \(\ell\) 和 \(r\),分别表示被跳过的第一个和最后一个选手的下标。注意,\(\ell\) 和 \(r\) 的下标范围为 \(0\) 到 \(N-1\)。如果有多个解,输出其中任意一个即可。
输入输出样例 #1
输入 #1
4 5
1 3 0 2 3
输出 #1
1 1
输入输出样例 #2
输入 #2
3 6
1 0 2 2 1 0
输出 #2
0 2
输入输出样例 #3
输入 #3
4 8
0 2 0 1 2 1 3 3
输出 #3
2 6
输入输出样例 #4
输入 #4
3 6
1 1 2 0 1 0
输出 #4
0 3
输入输出样例 #5
输入 #5
4 6
0 1 2 0 3 2
输出 #5
2 3
输入输出样例 #6
输入 #6
5 13
3 3 3 1 2 0 3 3 2 1 4 1 0
输出 #6
1 9
说明/提示
约束与评分
- \(1 \leq T < N \leq 500\,000\)
- \(0 \leq a_i \leq T-1\)
你的解答将在一组测试组上进行评测,每组有若干测试用例。要获得该测试组的分数,你需要通过该测试组的所有测试用例。
| 测试组 | 分值 | 限制条件 |
|---|---|---|
| 1 | 8 | \(N = T + 1\),即只有一支队伍会出现两次 |
| 2 | 11 | \(N = 2 \cdot T\),且每支队伍在前半部分和后半部分各出现一次 |
| 3 | 14 | \(1 \leq T < N \leq 500\) |
| 4 | 21 | \(N = 2 \cdot T\),且每支队伍均出现两次 |
| 5 | 22 | \(1 \leq T < N \leq 5\,000\) |
| 6 | 24 | 无额外限制 |
翻译由 ChatGPT-4.1 完成。
#include <iostream>
using namespace std;
int T,n,a[1000005],sum[1000005],L,R;
int main() {
cin>>T>>n;
for (int i=1;i<=n;i++) cin>>a[i];
int j;
for (j=n;j>0 && sum[a[j]]==0;j--) {
if (sum[a[j]]==0) sum[a[j]]++;
}
j++;
int L=0,R=j,Ans=n-j+1; //发礼物的区间长度
int Len=Ans;
for (int i=1;i<=n;i++) {
while (j<=n && sum[a[i]]>0) {
sum[a[j]]--;Len--;j++;if (j>n) break;
}
sum[a[i]]++,Len++;
if (sum[a[i]]>1) break;
if (Ans<Len) Ans=Len,L=i,R=j;
}
cout<<L<<" "<<R-2<<endl;
return 0;
}
/*
10
1 2 5 4 3 5 5 5 5 5
*/
浙公网安备 33010602011771号