#P1839. 「IOI2018」狼人

「IOI2018」狼人

题目描述

在日本的茨城县内共有 NN 个城市和 MM 条道路。这些城市是根据人口数量的升序排列的,依次编号为 00 到 N−1N-1。每条道路连接两个不同的城市,并且可以双向通行。由这些道路,你能从任意一个城市到另外任意一个城市。

你计划了 QQ 个行程,这些行程分别编号为 00 至 Q−1Q-1。第 ii(0≤i≤Q−10\le i\le Q-1)个行程是从城市 SiS_i 到城市 EiE_i。

你是一个狼人。你有两种形态:人形和狼形。在每个行程开始的时候,你是人形。在每个行程结束的时候,你必须是狼形。在行程中,你必须要变身(从人形变成狼形)恰好一次,而且只能在某个城市内(包括可能是在 SiS_i 或 EiE_i 内)变身。

狼人的生活并不容易。当你是人形时,你必须避开人少的城市,而当你是狼形时,你必须避开人多的城市。对于每一次行程 ii(0≤i≤Q−10\le i\le Q-1),都有两个阈值 LiL_i 和 RiR_i(0≤Li≤Ri≤N−10\le L_i\le R_i\le N-1),用以表示哪些城市必须要避开。准确地说,当你是人形时,你必须避开城市 0,1,⋯ ,Li−10,1,\cdots,L_i-1;而当你是狼形时,则必须避开城市 Ri+1,Ri+2,⋯ ,N−1R_i+1,R_i+2,\cdots,N-1。这就是说,在行程 ii 中,你必须在城市 Li,Li+1,⋯ ,RiL_i,L_i+1,\cdots,R_i 中的其中一个城市内变身。

你的任务是,对每一次行程,判定是否有可能在满足上述限制的前提下,由城市 SiS_i 走到城市 EiE_i。你的路线可以有任意长度。

输入格式

你需要实现下面的函数:

int[] check_validity(int N, int[] X, int[] Y, int[] S, int[] E, int[] L, int[] R)
  • N:城市的数量
  • X 和 Y:两个长度为 MM 的数组。对于每个 jj(0≤j≤M−10\le j\le M-1),城市 X[j] 都有道路直接连到城市 Y[j]。
  • S, E, L, 及 R:均为长度为 QQ 的数组,以表示行程。

注意,MM 和 QQ 是数组的长度,它们的值可以按照“注意事项”中的相关说明而取得。

对于每个测试样例,函数 check_validity 将被调用恰好一次。这个函数应返回长度为 QQ 的整数数组 AA。如果行程 ii 可以在满足前述限制的条件下完成,则 AiA_i(0≤i≤Q−10\le i\le Q-1)的值必须为 11,否则为 00。

数据范围与提示

  • 2≤N≤200 0002\le N\le 200\ 000
  • N−1≤M≤400 000N-1\le M\le 400\ 000
  • 1≤Q≤200 0001\le Q\le 200\ 000
  • 对于每个 0≤j≤M−10\le j\le M-1
  • 0≤Xj≤N−10\le X_j\le N-1
  • 0≤Yj≤N−10\le Y_j\le N-1
  • Xj≠YjX_j\ne Y_j
  • 你可以通过道路由任意一个城市去另外任意一个城市。
  • 每一对城市最多只由一条道路直接连起来。换言之,对于所有 0≤j<k≤M−10\le j<k\le M-1,都有 (Xj,Yj)≠(Xk,Yk)(X_j,Y_j)\ne(X_k,Y_k) 和 (Yj,Xj)≠(Xk,Yk)(Y_j,X_j)\ne(X_k,Y_k)
  • 对于每个 0≤i≤Q−10\le i\le Q-1
  • 0≤Li≤Si≤N−10\le L_i\le S_i\le N-1
  • 0≤Ei≤Ri≤N−10\le E_i\le R_i\le N-1
  • Si≠EiS_i\ne E_i
  • Li≤RiL_i\le R_i

子任务

  1. (7 分)N≤100N\le 100,M≤200M\le 200,Q≤100Q\le 100
  2. (8 分)N≤3 000N\le 3\ 000,M≤6 000M\le 6\ 000,Q≤3 000Q\le 3\ 000
  3. (34 分)M=N−1M=N-1 且每个城市最多与两条路相连(所有城市是以一条直线的形式连起来)
  4. (51 分)没有附加限制

评测程序示例

评测程序示例将按照以下格式读入输入数据:

  • 第 11 行:N M QN\ M\ Q
  • 第 2+j2+j 行(0≤j≤M−10\le j\le M-1):Xj YjX_j\ Y_j
  • 第 2+M+i2+M+i 行(0≤i≤Q−10\le i\le Q-1):Si Ei Li RiS_i\ E_i\ L_i\ R_i

评测程序示例将以如下格式把 check_validity 的返回值打印出来:

  • 第 1+i1+i 行(0≤i≤Q−10\le i\le Q-1):AiA_i