[CF1284] Hello 2020

Hello 2020

传送门

A - New Year and Naming

水题。 a.cpp 68169299

B - New Year and Ascent Sequence

模拟+二分/扫描题。 b.cpp 68172320

C - New Year and Permutation

简单排列组合。 c.cpp 68175209

D - New Year and Conference

(相交)区间题。

这题有多种做法……

首先,注意到答案是NO当且仅当存在两个会议,他们在一个地点冲突,而在另一个地点不冲突。

其次,有

\[[l,r]与[L,R]相交\iff\max(l,L)\le\min(r,R)\iff l<R,r<L \]

非随机化算法

题解

扫描线。

扫描\(a\),增加一个元素\(i\)时,看其他线段在\(b\)中是否全部与它相交。即,判断目前的所有元素中是否存在\(j\)使得\(eb_j < sb_i\)\(eb_i < sb_j\)

因此,只需用multiset维护\(eb_\max\)\(sb_\min\)即可。

注意:删除元素的时候应该使用multiset::erase(multiset::find(key))

我的做法

(原来的假算法在比赛结束后被我自己hack了……orz)

考虑一个区间\([sa_i,ea_i]\),判断有没有\(j\)满足\(ea_j < sa_i\)\([sb_i,eb_i]\cap[sb_j,eb_j]\ne\empty\).

将区间按右端点排序后,不与\(a_i\)相交的\(a_j\)构成一个连续区间。

问题转化为判断一个线段是否与另一个集合中的线段相交,线段树即可。

哈希

考虑单个会议

原题等价于,对于每一个会议,与其在\(a\)中相交的会议集合\(=\)与其在\(b\)中相交的会议集合。

#

There is another randomized approach involving hashes. You may assign random number to each lecture and then calculate for each interval the xor of numbers assigned to intervals it intersects. Now you should check that every lecture has same hashes in first and second places...

#

I think, scan-line should work. When the interval \([l_i,r_i]\) opens, you put \(h_i\) in the position \(are _i\) and when this interval closes you take the xor of all numbers on the \([l_i,∞)\).

考虑所有会议

原题等价于,在\(a\)中相交的会议对的集合\(=\)\(b\)中相交的会议对的集合。

#

Let's calculate value \(sumA=\sum_{i \, intersects \, j}(h_i\cdot h_j)\) by some modulo for segments in A and the same \(sumB\) for segments in B. Here, \(h_i\) are some random values. This can be calculated with scanline. The answer is "YES" iff \(sumA=sumB\).

随机化

考虑一个随机的集合,原题等价于,该集合在\(a\)中的相交的会议对数\(=\)\(b\)中相交的会议对数。

#

If there exists a pair of segments which intersects in one of the events and not the other then answer is NO. So each segment has to intersect with the same exact other segments in each events. This implies that for any subset the number of intersections in each event has to be the same.

So here's what I did: Take a random subset (50% chance of a segment being in it). Count number of intersections if Event A was chose, and same for Event B. If the number of intersections is diff output NO, otherwise repeat again with a diff subset(for 50 iterations). To count number of intersections, i sorted segment by left endpoint, then used binary search on each element.

E - New Year and Castle Construction

非常漂亮的一道计算几何题。有多种做法。

我的做法

由于这个东西看起来就很难计算,尝试简化所要求的值。

注意到一个神奇的性质:四边形的答案\(=\)三角形的答案\(\times (n-4)/2\)。这是由于点\(P\)如果被某四边形包含,那么其中恰有两个三个顶点的集合包含\(P\).

考虑如何计数三角形的答案:固定\(P_x\),考虑有多少个三角形包含\(P_x\)

首先,若\(\triangle P_iP_jP_k\)(顶点顺时针顺序)包含\(P_x\),那么可知\(P_k\)分别在\(\overrightarrow{P_iP_x}\)\(\overrightarrow{P_jP_x}\)的右、左侧。

\(P_x\)为原点极角排序,设\(f_i\)为使得\(P_xP_i\and P_xP_{f_i}<0\)\(\and\)表示叉积)的最小\(f_i>i\),那么包含\(P_x\)\(\triangle P_iP_jP_k\)的个数为

\[\sum_{j=i+1}^{f_i}(f_j-f_i) = \sum_{j=i+1}^{f_j}f_j-(f_i-i)f_i \]

前缀和维护即可。

e.cpp 68217260

不要写eps!不要写eps!!不要写eps!!!

题解

从五元组的数目=>答案。

#

We will take the approach of calculating \(\sum_{p \in S} f(p)\) itself, instead of computing each term independently. Consider all 5-point subsets out of \(n\) points. As no three points are collinear, there are three cases:

  • Convex hull has 3 vertices. We denote the number of such subsets as \(x_3\). In this case, the two vertices strictly inside the hull can be enclosed by other vertices (Draw a straight line connecting those two points, and extend the non-intersected edge toward one of them, to enclose the other). The contribution to the answer is \(2 \times x_3\).
  • Convex hull has 4 vertices. We denote the number of such subsets as \(x_4\). In this case, the point not in the hull can obviously be enclosed, but the points on the hull cannot be. The contribution to the answer is \(x_4\).
  • Convex hull has 5 vertices. We denote the number of such subsets as \(x_5\). In this case, no point can be enclosed. The contribution to the answer is 0.

We can see that the answer we want is \(2x_3 + x_4\). On the other hand, \(x_3 + x_4 + x_5 = \binom{n}{5}\), by definition.

Now here comes the magic. If we can compute the value \(3x_3 + 4x_4 + 5x_5\) somehow, then the answer can be easily derived. It turns out this can be done in \(O(n^2 \log n)\) time, by exploiting the form \(\sum_{i = 3}^{5} i \times x_i\). This quantity corresponds to the sum of edges of the convex hull for all 5-point subsets. Then, we can instead try to enumerate all \(O(n^2)\) possible edges, and count the number of 5-point subsets that contain each edge.

Consider each edge as being directed. In other words, we'll only consider edges where \((i, j)\) are adjacent in the counterclockwise direction. Then the number of possible 5-point subsets is simply \(\binom{l_{i, j}}{3}\), where \(l_{i, j}\) is the number of vertices that lies left to the directed vector \((i, j)\). \(l_{i, j}\) can be obviously counted in \(O(n^3)\) time. If we perform an angular sort for fixed \(i\), we can optimize this to \(O(n^2 \log n)\) time by using two pointers.

Writer: ckw1140

Solution code

Challenge: Find \(x_5\) in \(O(n^2 \log n)\).

某可推广做法

计算\(f(p)\)时,计算不包含\(p\)的四元组个数。

#

Here is a more intuitive explanation for E. Sorry if it's mentioned already.

Fix the point \(p\). Translate everything such that \(p\) coincides with the origin. Sort all the other points counter-clockwise. We shall now find the number of quadruples of points that don't form a polygon containing \(p\).

Now consider some point \(s\). Consider the half-plane \(H\) of points \(t\) such that the cross product \(s \wedge t\) is positive. For a quadrilateral with \(s\) to contain \(p\), it has to have at least one point from \(H\) and at least one point not from \(H\). Conversely, we will count the number of quadruples \((s, t_1, t_2, t_3)\) such that \(t_1, t_2, t_3 \in H\). It is just the binomial coefficient \(|H| \choose 3\).

Now do that for all \(s\) and all corresponding \(H\), in linear time, using the two pointers method.

With iterating over all \(p\) and sorting, the complexity is \(O (n^2 \log n)\).

F - New Year and Social Network

非常有趣的一道树的匹配题。

做法很容易理解,但是完全想不出来啊……有挺多细节的……

f.cpp 68654155

题解(节选)

递归地构造:在\(T_2\)上操作,为使递归成立……

Inductive Proof. Attempt 2

It would be good to make \(T_1\) static, since otherwise our induction will fail. Then, what about repeating induction over \((T_1, T_2 + {e} - {f})\)? Everything is good, but then we should also guarantee \(T_2 + {e} - {f}\) is a tree. Is it possible?

Lemma 2. For any \(e \in E(T_1) - E(T_2)\), there exists some edge \(f \in E(T_2) - E(T_1)\) such that \(T_1 - {e} + {f}\) and \(T_2 + {e} - {f}\) is a tree.

Proof. \(T_2 + {e}\) has exactly one cycle \(C\). Since \(T_2 + {e} - {f}\) should remain acyclic, \(f \in C\) should hold. The cycle consists of edge \(e\) and path from \(T_2\), we should find such \(f\) from the path in \(T_2\), such that its endpoint connects two different component of \(T_1 - {e}\). Label the vertices in the path by its component membership of \(T_1 - {e}\). Since \(e\) itself connects the different component, there should exist a edge in the path, which connects different component. Take it.

Now, as \(T_1 - {e} + {f}, T_2 - {f} + {e}\) is both acyclic, we can create the bijection \({e \rightarrow f}\), and also take \((T_1, T_2 - {f} + {e})\) for the induction stage. This proof also gives a straightforward \(O(n^2)\) algorithm for finding the answer.

\(O(n\log n)\)

When we fix \(e \in E(T_1) - E(T_2)\), finding the component where each vertices lie is easy: This can be done by preprocessing \(T_1\) with a single depth-first search. Using this to find the \(f\) is a different story: We have dynamically changing tree of \(T_2\), which is hard to maintain.

On the other hand, since Lemma 2 is symmetric, we can rather fix \(f \in E(T_2) - E(T_1)\) and find \(e\) instead. In this case, if we can know which subtree that a vertex belongs for \(T_2 - {f}\):

  • If \(f = {u, v}\), find the path between \(u \rightarrow v\) in \(T_1\)
  • If \(LCA(u, v)\) belongs to same component in \(u\), then find \(f\) in path \(v \rightarrow LCA(u, v)\). Otherwise, find \(f\) in path \(u \rightarrow LCA(u, v)\).
  • Now, you can find \(e\) using binary search on paths, which can be implemented with binary lifting

Since \(T_1\) is static, we can afford all these operation in \(O(n \log n)\) time preprocessing. Now the point is to maintain \(T_2\) to support subtree membership query. This can be done straightforwardly using Link-Cut tree or Euler Tour tree using \(O(\log n)\) query time, which results in \(O(n\log^2 n)\) time, but this is too slow (at least for us) to pass.

Now from this point, we will assume \(E(T_1) \cap E(T_2) = \emptyset\). We have a freedom over choosing \(f\), so let's choose the \(f\) as the edge connecting the leaf. The good property of leaf is that the subtree membership query is very easy: You can simply compare the vertex number. So, if we choose such \(f\), we can find \(e\) easily.

What about changing the tree \(T_2\) to \(T_2 - {f} + {e}\) ? Note that, After \(T_2\) becomes \(T_2 - {f} + {e}\), we don't have to care about \(e\) because it's in the intersection of \(T_1\) and \(T_2\). We can think about contracting the edge \(e\): After adding an edge \(e\) we can not delete, so in the component point of view, they are always in the same component: So we can remove the leaf edge \(f\), and contract the ends of \(e\). For the data structure to maintain these components, we can use Union-Find.

G

毒瘤拟阵题……

待学习。

Matroid intersection in simple words 友链

题解

1284G - Seollal

The problem asks us to find a spanning tree on a grid graph, where some vertices are not allowed to be leaves. Let's denote such set of vertices as \(S\). Note that, per the problem statement, this set is independent. Thus, there exists no edge connecting two vertices in \(S\). Now, we present the following theorem.

Theorem. We can find a desired spanning tree if and only if there exists an acyclic edge subset where every vertex in \(S\) has a degree exactly 2.

Proof.

\(\leftarrow\): Since it is an acyclic edge subset, we can obviously expand it to a spanning tree by arbitrarily adding edges to connect different connected components. Vertices with degree at least 2 are not leaves.

\(\rightarrow\): As noted above, \(S\) is independent, and it has degree at least 2 in the desired spanning tree. Thus, we can pick any two incident edges for each vertex in \(S\).

Now, all that is left is to find such an acyclic edge subset. In general, as \(S\) is independent, we can pick two arbitrary incident edges, but this does not guarantee that the subset is acyclic. One can try to use a non-polynomial solution strategy, such as storing connection profiles in a DP, but the input is a bit too large for that.

Our solution is polynomial, and we will use a stronger tool that is known as matroid intersection. From now on, we will assume that the reader has familiarity with matroids as well as how to compute the intersection of two matroids.

Let's relax the degree condition to at most 2 instead of exactly 2. Now, the acyclic condition corresponds to a graphic matroid, and the degree condition corresponds to a choice matroid. By using Edmond's algorithm, we can find an independent set of maximum size. The exact degree condition is satisfied if and only if the maximum independent set has size \(2|S|\), so we can know whether such an edge set exists, and if it exists we can also get a certificate which is then used to print the answer.

In our matroid, we can implement Edmond's matroid intersection algorithm in \(O(E^3)\) time where \(E\) is the size of the ground set. As \(E\) is about \(2nm\), the final time complexity is \(O(n^3m^3)\) with low constants, just like any other augmenting-path algorithms.

Writer: ko_osaga

Solution code

posted @ 2021-06-17 21:47  frank3215  阅读(41)  评论(0编辑  收藏  举报