AtCoder Beginner Contest 347
很快做完了 AB。
然后 C 就不会做了。随便想了个看似正确的就交了,结果 WA*1。
后来有交了 4 发,一发比一发离谱。
发现 D 不难,是一个状态数 \(60 \times 60 \times 60\) 的 DP,但是貌似细节很多。写了大约 20 分钟后无伤过了,发现压根没有需要处理的细节。
这时是 57min。
读完 E 的题面,并简单模拟了一下样例就秒了。在 66min 过了。
然后发现 F 是不可做题,就回来肝 C。期间改了无数个写法,想着因为 WA*1 所以肯定是有边界之类的细节没有特判。想到最后也没过。
赛后在 Luogu 发现做法假了。
C - Ideal Holidays
-
一周有 \(a + b\) 天,其中前 \(a\) 天为假日,后 \(b\) 天为工作日。
接下来会有 \(n\) 件事情,第 \(i\) 将事情在接下来的第 \(d_i\) 天发生。当前是第 \(1\) 天。
你不知道今天是星期几。问是否有可能这 \(n\) 件事情都在假日里发生。
-
\(n \le 2 \times 10^5\),\(1 \le a, b \le 10^9\),\(1 \le d_1 < d_2 < \dots < d_n \le 10^9\)。
假设当前是星期 \(x\),也就是一个星期中的第 \(x\) 天。那么「所有事情都在假日发生」就可以转化为「所有 \(i \in [1, n]\) 都满足 \((d_i + x) \bmod (a + b) < a\)」。
最朴素的想法就是让除以 \(a + b\) 余数最小的一天成为一个星期的第一天,然后计算出今天是星期 \(x\),再判断是否对于所有事情都满足。
但是这样做会 WA*1。解决方法是如果按照上面方法得不到一个解,就随机某天 \(i\) 并让第 \(b_i\) 天成为这个星期的第一天。处理方法与上面类似。
时间复杂度 \(\Theta(nv)\),其中 \(v\) 是随机次数。这里取 \(v = 50\)。
$\color{blue}\textbf{Code}$
int n, a, b, d[N];
bool chk(int p) {
p %= a + b;
int t = a + b - p;
if (!p) t = 0;
for (int i = 1; i <= n; ++ i )
if ((d[i] + t) % (a + b) >= a)
return false;
return true;
}
void Luogu_UID_748509() {
fin >> n >> a >> b;
for (int i = 1; i <= n; ++ i ) {
fin >> d[i];
d[i] %= a + b;
}
sort(d + 1, d + n + 1);
bool flg = chk(d[1]);
for (int i = 1; i <= 50 && !flg; ++ i )
flg |= chk(d[rand() % n + 1]);
puts(flg ? "Yes" : "No");
}