Google Codejam Round 2 && POJ Challange Beta 1

GCJ 应该是可以骗到一件衣服的 - -

POJ 的奖品居然没骗到 >__< 做到一半机房断网了于是 #11 真是不能更爽

Google Codejam Round 2

A

一开始看错题了……

显然最后每个人的路线是不相交的,允许包含。于是上车点与下车点构成了括号序列。

然后用栈处理一下就好。

B

假设第一步是二分吧(感觉有不用二分的方法),那么我们的问题就是判定一个人最好/最坏排名是多少。

共有 TT 个人,令 f(x,T)f(x, T) 表示能力排名为 0x<T0 \leq x < T 的人最差排名是多少。考虑 x=0x = 0 的情况,易得 f(x,T)=T1f(x, T) = T - 1 。否则,最差情况下, xx 会被打败,而且下一轮中 xx 的能力值排名是所有可能的值中最大的。 xx 之前有 xx 个人比他强,进入败者组的人至多有 x12\lfloor\frac{x - 1}{2}\rfloor 个人,所以有 f(x,T)=T2+f(x12,T2)f(x, T) = \frac{T}{2} + f(\lfloor\frac{x - 1}{2}\rfloor, \frac{T}{2})

最好情况类似,令 g(x,T)g(x, T) 表示 xx 最好可以打败多少人,可以得到当 x=T1x = T - 1 时有 g(x,T)=0g(x, T) = 0 ,否则有 g(x,T)=T2+g(x+12,T2)g(x, T) = \frac{T}{2} + g(\lfloor\frac{x + 1}{2}\rfloor, \frac{T}{2})

python 真是极好的。

C

根据 LIS 和 LDS 序列可以构出一个拓扑图,一条有向边 sts \to t 表示 xs<xtx_s < x_t 。我们要求这个拓扑图的一个拓扑序列,满足 1 出现的位置尽量靠前,在此基础上, 2 出现的位置尽量靠前 etc 。

直接上伪代码吧 = =||

def dfs(x) : # 要使得 x 尽量先出来
	if x 已经在拓扑序中 :
		return
	ys <- 所有要使得 x 出来必须出来但是还未出来的点
	sort ys increasingly
	for y in ys :
		dfs(y)
	Q += [x]

Q = []
for i from 1 to n :
	dfs(i)
# 然后 Q 就是要求的拓扑序

这样做显然是 O(n2)O(n^2) 的。

其实有个更好写的 O(nlogn)O(n \log n) 的方法。反向建图,每次选择标号最大的点出来,相当于求出逆拓扑序。

D

计算几何,哈哈哈哈。

POJ Challenge Beta 1

有中文题面,这真是极好的。

A

a(a+b)=c2a(a + b) = c^2 可得 a=b2+4c2b2a = \frac{\sqrt{b^2 + 4c^2} - b}{2} ,可以发现只要 b2+4c2\sqrt{b^2 + 4c^2} 为整数即可,奇偶性可以保证。

b2+4c2=d2b^2 + 4c^2 = d^2b2=(d2c)(d+2c)b^2 = (d - 2c)(d + 2c) 。易知 d2c4d - 2c \leq 4 ,所以枚举 d2cd - 2c ,看看是否存在整数 cc ,如果存在 cc 就可以直接求 dd 然后求 aa 了。

为啥 d2c4d - 2c \leq 4 ?当 bb 为奇数时显然 d2c=1d - 2c = 1 ,当 bb 为偶数时 d2c=2,d+2c=b22d - 2c = 2, d + 2c = \frac{b^2}{2}d2c=4,d+2c=b24d - 2c = 4, d + 2c = \frac{b^2}{4} 中至少有一组可行解。(其实继续分析下去可以直接找到规律,只不过这样已经很好写了于是就直接写了。)

B

一个 O(n3)O(n^3) 的 dp 是显然的, fi,jf_{i, j} 表示区间 [i,j][i, j] 的最优解,枚举根进行转移。

然后我就不会了 = =

不过我是怎么在 20min 过的呢……因为我看到有人(wkn ?)在 15min 过了,于是觉得这个题应该是可做的,于是猜了个结论: fi,jf_{i, j} 的根只可能是 iijj 。随机生成了几组极限数据试试发现是对的……然后就没有然后了……

感觉如果按照 dp 的一般优化思路去想的话应该也是可做的。

C

如果一个数同时出现在两组限制中,那么这两组限制必定是连续的,也就是最后的限制就是若干条链,每条链分别搞搞就好了。

感觉好多细节啊不想写啊。你要牛逼就写 PQ 树去吧哈哈哈哈。

D

std 的想法大概是 dp 吧, fi,jf_{i, j} 表示最后一条线段是 iji \to j ,转移的话利用极角序优化一下就好了。

我写的另外一种方法,但是 WA 了。

考虑枚举最低点。两边点到这个点的斜率递增,求出斜率后直接 LIS 。为啥我会错……难道老了连 LIS 都不会了么 T_T

E

果的数据结构题。

依次 dfs 每个点。对于 (a,b)(a, b) ,我们要求所有的 (c,d)(c, d) 数目使得 (c,d)(c, d) 能够覆盖 (a,b)(a, b) ,我们在 dfs c 的时候在 d 点放个标记,那么在 dfs a 的时候就相当于查询 b 到根的路径上有多少个标记。显然 dfs 序 + 树状数组。

F

显然是原题。

半平面交是 O(n2logn)O(n^2 \log n) 的吧。似乎我估错复杂度以为是 O(n3logn)O(n^3 \log n) 的就没写了 →_→

模拟退火 balabala 不知道怎么样。你要牛逼就写 Voronoi 图去吧哈哈哈哈。