#dDDLDPybttg050504. 1600:【例 4】旅行问题

1600:【例 4】旅行问题

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

原题来自:POI 2004

John 打算驾驶一辆汽车周游一个环形公路。公路上总共有 nn 个车站,按顺时针编号 11nn。每站都有若干升汽油(有的站可能油量为零),每升油可以让汽车行驶一千米。John 必须从某个车站出发,一直按顺时针(或逆时针)方向走遍所有的车站,并回到起点。在一开始的时候,汽车内油量为零,John 每到一个车站就把该站所有的油都带上(起点站亦是如此),行驶过程中不能出现没有油的情况。

任务:判断以每个车站为起点能否按条件成功周游一周(顺时针和逆时针都要考虑)。


输入格式

第一行是一个整数 nn,表示环形公路上的车站数;

接下来 nn 行,每行两个整数 pi,dip_i, d_i,分别表示第 ii 号车站的存油量(升)和第 ii 号车站到下一站的距离(千米)。

注意:第 nn 站的下一站是第 11 站(环形)。


输出格式

输出共 nn 行,如果从第 ii 号车站出发,一直按顺时针(或逆时针)方向行驶,能够成功周游一圈,则在第 ii 行输出 TAK,否则输出 NIE


样例

样例输入

5
3 1
1 2
5 2
0 1
5 4

样例输出

TAK
NIE
TAK
NIE
TAK

样例解释

车站数据(pi,dip_i, d_i):

  1. (3,1)
  2. (1,2)
  3. (5,2)
  4. (0,1)
  5. (5,4)

顺时针判断:

ai=pidia_i = p_i - d_i(表示从 ii 站到 i+1i+1 站油量的净变化)。

环形前缀和 si=a1+a2++ais_i = a_1 + a_2 + \dots + a_i(对 nn 取模意义下累加,但这里我们做的是环形扫描)。

条件:从 ii 出发顺时针可行当且仅当 j[i,i+n1]\forall j \in [i, i+n-1]sjsi10s_j - s_{i-1} \ge 0,即最小前缀和 0\ge 0

用单调队列维护窗口最小值即可。

逆时针同理,但需要反转方向并重新计算 aia_i

最终每个站如果顺时针或逆时针有一个可行,输出 TAK,否则 NIE

样例结果:

  • 站1:可行
  • 站2:不可行
  • 站3:可行
  • 站4:不可行
  • 站5:可行

数据范围

对于全部数据:

  • 3n1063 \le n \le 10^6
  • 0pi2×1090 \le p_i \le 2\times 10^9
  • 0<di2×1090 < d_i \le 2\times 10^9

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}

提示
此题需要分别判断 顺时针逆时针 两个方向。

步骤

1. 顺时针

  • ai=pidia_i = p_i - d_i
  • 构造长度为 2n2n 的序列 b=[a1,a2,,an,a1,a2,,an]b = [a_1, a_2, \dots, a_n, a_1, a_2, \dots, a_n]
  • 计算前缀和 s0=0,si=si1+bis_0=0, s_i = s_{i-1} + b_iii112n2n);
  • 对于起点 ii1in1 \le i \le n),需要检查 si,si+1,,si+n1s_{i}, s_{i+1}, \dots, s_{i+n-1} 是否都 si1\ge s_{i-1},即 minj[i,i+n1]sjsi1\min_{j \in [i, i+n-1]} s_j \ge s_{i-1}
  • 可以用单调队列维护窗口 [i,i+n1][i, i+n-1]sjs_j 最小值。

2. 逆时针

  • 逆时针时,从 ii 出发先到 i1i-1 站,再到 i2i-2,以此类推。
  • 重新定义 ai=pidi1a'_i = p_i - d_{i-1},其中 d0=dnd_0 = d_n(因为第 11 站的前一站是第 nn 站);
  • 类似顺时针,构造 2n2n 的序列并求前缀和,用单调队列判断。

3. 合并

  • 如果 ii 顺时针或逆时针有一个可行,则输出 TAK,否则 NIE

复杂度O(n)O(n)

注意:由于 nn 很大,需要高效输入输出,使用 scanf/printf 或关闭同步的 cin/cout