Codeforces 698B Fix a Tree
链接
题意
给出一个\(n\)个结点的父结点,改变最少的结点的父结点使得图变为一棵有向树。
思路
dfs搜出所有的环,指定新的根,把环解开后连到根上就好啦。
代码
1 |
|
给出一个\(n\)个结点的父结点,改变最少的结点的父结点使得图变为一棵有向树。
dfs搜出所有的环,指定新的根,把环解开后连到根上就好啦。
1 | #include <cstdio> |
给出一个\(n\)个结点的树,有\(q\)个查询,对于每个查询输出以\(x\)为根的子树的重心。
在两个树合并后,新的重心在链接原来两个树重心的路径上。因此可以dfs求解。
可以参考这篇博客:Codeforces 685B - Kay and Snowflake | Sengxian's Blog
1 | #include <cstdio> |
给出一个浮点数,转化成标准形式。
1 | #include <cstdio> |
给出\(n\)个区间,问所有选择\(k\)个不同区间的方法下它们相交区间的长度和。
离散化之后用扫描线维护有多少个区间包含当前子区间,然后当前区间的贡献为\({num \choose k} \cdot len\)。
1 | #include <cstdio> |
给出序列a和序列b,问有多少组l、r满足\(\max \limits_{i=l}^{r}a_i=\min\limits_{i=l}^{r}b_i\)。
对于左端点固定的区间,最大值随右端点的单调不降,最小值单调不增。 所以\(\max \limits_{i=l}^{r}a_i-\min\limits_{i=l}^{r}b_i\)也是单调不降的。因此可以对于每个左端点二分满足条件的右端点的区间求解。
1 | #include <cstdio> |
给出\(n\)个点,每个点都有一条弧连接着一个其他的点,对于给出的弧,可以选一部分进行反转使得图中没有环,输出操作的方法数对\(10^9+7\)取模后的值。
易得,弧的方向对结果不产生影响,将弧转为无向边考虑。显然,对于任意连通分量都至多有一个环。每个环的反转方式为\(2^e-2\),不在环中的每条边的反转状态任意。最终的结果为\(2^{n-\sum e} \prod {\left(2^e-2\right)}\)。
1 | #include <cstdio> |
给出\(n \times m(1 \leq n, m \leq 1000)\)的矩阵,有\(q(1 \leq q \leq 10000)\)次操作,每次给出两个大小相同的且不相交无公共边的子矩阵,交换两个子矩阵,输出\(q\)次操作之后的矩阵。
用十字链表储存矩阵,每个点记录下面和右面两个方向的编号。这样对于每次操作,可以在\(O(n + m)\)的时间内完成。
1 | #include <bits/stdc++.h> |
给出一个可重集,最初其中有一个0,有插入删除询问三种操作。对于询问操作,输出给出的数字和可重集中的数字异或的最大值。
对可重集中的数字建trie树,查询时每次都优先走于所给数字当前位相反的边,达到底层的结点即为与给出数字异或和最大的结点。
1 | #include <bits/stdc++.h> |
给出\(n(1 \leq n \leq 100000)\)个字符串,翻转和字符串的费用。现在对部分字符串进行反转操作,使得最后的字符串序列字典序单调不降。输出最小花费。
显然的\(dp\)问题,状态\(dp[i][0]\)表示前\(i\)个字符串,第\(i\)个不翻转时的最小花费,\(dp[i][1]\)表示前\(i\)个字符串,第\(i\)个翻转时的最小花费。
1 | #include <bits/stdc++.h> |
给出\(n \times m\)的矩阵,矩阵中的数分为了\(k\)个分量,其中\(1 \leq n, m, k \leq 2000\)。每个点都有各自的权值。有两种操作:
其中查询操作不超过2000次。
记录查询时分量的开关状态,然后用二维树状数组计算出分量对每个查询的贡献。
1 | #include <cstdio> |