200 likes | 265 Views
TJOI2010 题解. Middle. 此题解决方法很多,比较直接的解法是用平衡二叉树,在结点处标记每棵子树的儿子数,即可在 O(logn) 时间内完成每次操作。 注意如果采用非平衡的树结构,对于特殊构造的数据(比如按递增顺序依次加入)会退化到 O(n^2) 导致 TLE. Middle. 平衡二叉树的实现较为繁琐。实际上,针对此题只要求“中位数”的特殊情况,可以用两个堆来实现。两个堆分别存储一半元素,较小的一半用大顶堆,较大的一半用小顶堆。 每次求中位数只需取出较小一半的最大元素即可。插入新元素时与中位数比较来确定插入到哪个堆里,同时可能会把该堆的堆顶元素移入另一个堆。.
E N D
Middle • 此题解决方法很多,比较直接的解法是用平衡二叉树,在结点处标记每棵子树的儿子数,即可在O(logn)时间内完成每次操作。 • 注意如果采用非平衡的树结构,对于特殊构造的数据(比如按递增顺序依次加入)会退化到O(n^2)导致TLE
Middle • 平衡二叉树的实现较为繁琐。实际上,针对此题只要求“中位数”的特殊情况,可以用两个堆来实现。两个堆分别存储一半元素,较小的一半用大顶堆,较大的一半用小顶堆。 • 每次求中位数只需取出较小一半的最大元素即可。插入新元素时与中位数比较来确定插入到哪个堆里,同时可能会把该堆的堆顶元素移入另一个堆。
Movie • 对于N<=15的情况,可以暴力枚举解决 • 标准解法为网络流,可看作最大权闭合子图的扩展问题。 • 每个电影看作一个点,新加源S和汇T,若电影i的体验值v[i]为正,则连边S到i,容量为v[i],若i的体验值v[i]为负,则连边i到T,容量为|V[i]|。若i和j有关联d[ij],则连边i到j,容量为d[ij]。 • 求S到T的最大流即最小割C,所有正的体验值v[i]之和减去C,即为所求。
Movie • 解释:在割里与S同侧的点集即为选出来看的电影。每个割包含三种边:从S到某个正体验值的电影的边(即没选的正体验值),从某个负体验值到T的边(即选了的负体验值),以及左边被选出,右边未被选出的边(即有前后关联的电影而我们只选了前一部的损失值)。所有正的体验值之和是我们最大可能的收益,则这三部分都可以看作某种“损失”,求最小割正是使得损失最小,故收益最大。
Weather • 矩阵乘法。构造N*N的矩阵A: • A[i+1][i] = 1 (1 <= i < n) • A[i][n] = 1 (1 <= i <= n) • 其余位置都为0
Weather • 则可发现,若第i天之前的n天组成行向量 R = [wi-n, wi-n+1, …, wi-2, wi-1],则 R*A = [wi-n+1, …, wi-2, wi-1, wi] • 设开始时n天的向量为R0 = [w1,w2,…wn], • 则R0*Am-n的最右端元素即为第m天的天气 • 矩阵的幂Am-n可以用二分法(倍增法)在log(m)的时间内求出,总的复杂度为O(n^3*logm)
Cutting • 二分答案+树形DP • 假设答案为p,将每个点的权值设为x[i] = v[i]-p*w[i],问题变成求不少于K个点的权值和最大的子树。若此权值和大于0,说明p过小,否则说明p过大。以此缩小一半的范围,继续二分直至精度满足要求为止。
Cutting • 求不少于K个结点的总和最大的子树: • 用dp[i][j]表示在以i点为根的子树中恰好选择了j个点(且选择了i点)的最大权值和 • 计算dp[i]时,边界条件dp[i][0] = 0, dp[i][1] = x[i] • 依次对i的每个儿子t进行类似“背包”的dp: dp[i][j+c] >?= dp[i][j] + dp[t][c] (c >= 1) • 最后统计所有 dp[i][j] (j >= K) 的最大值即可 • 总复杂度O(logC*n^3)
River • 最直接的做法:矩形面积并 • 每条污染河流都可看作一个2*N的矩形 • 以每个矩形的x1,x2坐标作为“事件点”,想象一条线从左向右扫描,维护一个线段树。遇到矩形的左边,就把相应线段加入,遇到矩阵的右边就删除,同时动态统计当前线段树中被覆盖的长度。 • 参考1999年陈宏的国家集训队论文
Seq • 观察允许的“模式”可以发现,只有6种情况可行: 01, 03, 10, 12, 21, 30,可以发现序列一定是奇偶交替的。即每个位置只有两种选择{0,2}或者{1,3} • 一个简单过滤:如果一条规则包含了超过两个奇数位或者超过两个偶数位,则必无解(于是实际上规则长度不会超过4)
Seq • 实际上此问题可转化为2-SAT问题,把每个位置看作一个变量,取0或1当做“假”,取2或3当做“真”,则题目中的限制可表示成一系列逻辑表达式: • (1)相邻两元素x,y不能同真,因为不允许23,32模式。可表示成(~X OR ~Y) • (2)两元素x,y不相等。可表示成(X OR Y) AND (~X OR ~Y)
Seq • 求解2-SAT问题的方法: • 对每个变量x建立两个点,分别表示x和~x • 对每个(x OR y)形式的限制,连有向边(~x y)和(~y x)。分别表示“若选择了~x必须选择y”和“若选择了~y必须选择x” • 其他形式的限制,例如(~x OR y),均可类推 • 求此图的强连通分量,若发现存在某变量p和~p在同一强连通分量中,则无解,否则必有解
Clean • 50%的数据:状态压缩dp (插头dp) • 用dp[i][j][mask]表示当前考虑(i,j)格子,且其上的各个位置的状态是否能取到mask。Mask是一个m+1位的二进制串,表示每个位置是否是“开放”的“插头”。 • 复杂度O(M*N*2^(M+1))
Clean • 100%的数据:网络流(匹配?) • 对矩阵黑白交替染色,相邻格子间连边,于是可得到一个二分图。 • 可以发现每条环线必然进出每个格子各一次,也即每个点都和另一侧两个点“匹配” • 所以我们要找一个每个点都恰好关联两条边的“匹配”
Clean • 若黑白色点数不等,必无解 • 添加源S和汇T,S向每个黑色点连边,容量为2,每个白色点向T连边,容量为2。每个黑色点向相邻白色点连边,容量为1。 • 求最大流,若最大流能把所有S发出的边充满,则输出YES
Coin • 30%的数据:普通的背包问题 • 用dp[i][j][k]表示前i个数里选择j个数,能否使得和为k • 100%的数据: • 将数分成均等的两部分(每部分不超过15),分别计算出2^15种可能的组合。
Coin • 将右侧按照包含元素的个数分类,并按元素的和排序 • 对于左半部分的每种组合,根据其元素个数可知在右侧还需要多少元素,也可求出其“选与未选”之差delta。在右侧相应类别里二分查找使结果最接近的值。 • 最坏情况计算量大约为215*log(215)
Reading • 比较简单的杂题 • 对所有文章进行一遍扫描,对每个单词w保存一个列表list[w],表示w在哪篇文章中出现过。具体实现上可用hash将单词映射到一个数值,然后拉出一个链表。 • 对于每个查询,进行同样的hash计算,将对应的链表输出即可