2021 暑假训练记录 Ⅰ

7.29

晚上

Codeforces Round #735 (Div. 2)

补题进度:5 / 5。

状态正佳,AC 了 ABCD。

A:观察一下可以发现答案即为 \(\max\{a_i\times a_{i+1}\}\)

B:想了比较久,因为 \(k\le 100\) 所以 \(n\) 大的时候直接暴力找 \(n\)\(1000\) 个左右元素即可。

C:按位从大到小贪心。

D:比较好的构造,答案为:

  • 如果 \(n\) 是奇数,答案可以是 ccccc...cabccccc....c
  • 否则就是 cccc...cacccc...ccc
  • 前面的 c 的个数 = 后面 c 的个数 - \(1\)

E:还没来得及补。 AC at 2021.8.1 17:00。

注意到原问题等价于给 \(n-1\)​ 条边定向后每个点的入度,因此总方案数为 \(2^{n-1}\)

而且只有在 \(k\)\(n-1\) 的约数时 \(f_k > 0\)

考虑 \(k>1\)​ 的情况,可以发现 \(f_k\) 至多为 \(1\)。证明可见参考题解。

这样的话我们就可以枚举 \(n-1\) 的每一个约数,依次 dfs,最后算出来 \(f_1\)

复杂度 \(\mathcal{O}(n\times \omega(n-1))\)\(\omega(n-1)\)\(n-1\)​ 的质因子个数。

代码

参考题解

\(\text{Rating Change}\)​​​​​​​:\(1779\to 1923\)​​ ,\(+144\)​​,Became \(\texttt{Candidate Master}\)​​​​​​​​。

7.30

上午

暑假物理作业 6~8。

下午

帮 Tony102 验考试题。

T2 dsu on tree 裸题。

T4 可以发现把字母映射成 \(0\sim 2\) 后每一次操作后数字之和 \(\mod3\)​ 不变,然后可以直接 DP。类似的题有 CF1421E

另外两题还没怎么做 \(\texttt{/kk}\)

原题:ARC101E Ribbons on Tree、CF570D Tree Requests、CF725G Messages on a Tree、ARC094F Normalization。

进度:

题目 AC时间
T1 7.31 12:21
T2 7.30 16:01
T3 X
T4 7.30 17:36

晚上

Educational Codeforces Round 112 (Rated for Div. 2)

补题进度:6 / 6。

过了 ABCDE,但罚时 -3。。。

A:因为 \(\frac{6}{15}=\frac{8}{20}=\frac{10}{25}\),所以只需要将 \(\le 10\) 的情况判掉就可以直接算了。

B:模拟。容易发现新放一个只能放在四个角上,四种情况都判一遍即可。

C:直接前缀和。\(ans=\min\limits_{i=1}^n\{\max\{sum_{1,n}-sum_{1,i-1}, sum_{2,i-1}\}\}\)

D:最终答案序列只可能是 abcacbbacbcacabcba \(6\) 种字符串循环得到,直接前缀和取 \(\min\) 即可。

E:按照 \(w\) 排序,线段树维护区间覆盖次数,区间能删就删。容易证明这样贪心是对的。

F:听说是启发式合并(咕咕咕 AC at 2021.7.31 15:35。

结论:合法的图中每条边一定至多属于一个环。

证明:考虑两个环的交如果不为空,那么这个交集组成的环就一定权值为 \(0\),不合法。

把询问离线下来,容易发现连接两个连通块的边一定是合法的。然后对这个森林树剖,用一颗线段树维护区间内的点是否被覆盖(可以区间赋值),然后注意一些细节即可。

代码

参考学习

\(\text{Rating Change}\)​​​:\(1923\to 1974\)\(+51\)​​​。

7.31

上午

数学暑假作业 5~6。

ARC101E Ribbons on Tree & Tony102 考试 T1

容斥 + 树形 DP,一道很好的题目。

参考学习

下午

【模板】Prufer 序列

很好的题解

补完了 Educational Codeforces Round 112 (Rated for Div. 2) 的 F。

8.1

上午

数学暑假作业 7 & 英语暑假作业 5~6

下午

补完了 Codeforces Round #735 (Div. 2) 的 E。

晚上

Codeforces Round #736 (Div. 1)

补题进度:4 / 6

A:把边定向,从编号小的连向编号大的,答案就是图中出度为 \(0\) 的点的个数,这个很好动态维护。

B:求出差分数组,然后求出最长的 \(\gcd>1\) 的区间,可以二分 + ST 表,注意一些细节(\(n=1\)、差分数组要取绝对值)。

C:还鸽着。 AC at 2021.8.2 11:54

容易发现题目就是要求 \(\sum\limits_{i=1}^n \binom{3i}{x}\)

考虑 DP,设 \(dp_{x,m}=\sum\limits_{i=0}^{n-1}\binom{3i+m}{x}\)

比较显然的是,\(dp_{x,0}+dp_{x,1}+dp_{x,2}=\binom{3n}{x+1}\)

然后就考虑转移,并且反复用 \(\sum\limits_{i=0}^n \binom{i}{j}=\binom{n+1}{j+1}\) 这个式子,可以得出以下 \(3\) 个式子:

  • \(dp_{x,1}=dp_{x,0}+dp_{x-1,0}\)

  • \(dp_{x,2}=dp_{x,1}+dp_{x-1,1}\)

  • \(dp_{x,0}=\frac{\binom{3n}{x+1}-2dp_{x-1,0}-dp_{x-1,1}}{3}\)

其中第三个式子可以通过前面的式子化简得到,这里不再赘述。

那么答案就是 \(dp_{x,0}+\binom{3n}{x}\)

D1:

因为图中的点的坐标都是偶数,所以三角形面积就一定是偶数。

根据皮克定理(\(S=a+\frac{b}{2}-1\),其中 \(a\) 表示多边形内部的点数,\(b\) 表示多边形落在格点边界上的点数,\(S\) 表示多边形的面积),因为 \(S\) 都是偶数,要想让 \(a\) 是奇数,那么 \(b\) 就一定是 \(4\)​ 的倍数,问题就变成了统计有多少个三角形边界上有 \(4\) 的倍数个整点。

因为连接点 \((x_1,y_1)\)\((x_2,y_2)\) 的线段上的整点数量是 \(\gcd(\Delta x, \Delta y)\),而这题中 \(\gcd\) 只可能为 \(0\)\(2\),所以直接开桶统计即可。

代码

\(\text{Rating Change}\)​:\(1974\to 2040\)​,\(+66\)​。

8.2

上午

数学暑假作业 8。

补了 Codeforces Round #736 (Div. 1) 的 C。

下午

[ZJOI2008]泡泡堂

田忌赛马类的贪心,比较简单。

8.3

上午

英语暑假作业 5~7

下午

Note:以下内容大部分来自 Cjzjy《图论》课件(2021.7.26)。

UVA11380 Down Went The Titanic

经典的拆点。

将次数限制为 \(k\)​ 的点 \(i\)​ 拆成入点 \(i_{in}\)​ 和出点 \(i_{out}\)​,add(i_in, i_out, k),对原图中的边 \((x,y)\)​,按照题目要求连边。


[TJOI2013]循环格

回路模型。

题目要求构成回路的网络流建模方法:

因为回路中的点的入度和出度都为 \(1\)​,所以考虑入度和出度匹配。即将点 \(i\)​ 拆为入点 \(i_{in}\)​ 和出点 \(i_{out}\)add(s, i_in, 1)add(i_out, t, 1)。对原图中的边 \((x,y)\)add(x_in, y_out, 1)

注意是入点连向出点,不要与拆点的连边方式弄混!

这道题中要求最小次数,因此考虑最小费用最大流。

一个格子的入点向四周格子的出点连边,该格子上箭头指向的格子费用为 \(0\),其他格子的费用为 \(1\),向 \(s\)\(t\) 连的边费用为 \(0\),所有边流量为 \(1\)


CF387D George and Interesting Graph

题意:

\(n\) 个点 \(m\)​ 条边的有向图中加边和删边,构成有趣图,求最小操作次数。

有趣图定义:

  • 有一个中心,满足此点有自环,且与其他结点有双向边。

  • 除中心点外的结点,满足出度 = 入度 = \(2\)

\(\texttt{Data Range}\)​:\(2 \le n \le 500\)​,\(1 \le m \le 1000\)​,图没有重边。

一道很好的网络流题。

因为中心点去掉后,点的入度和出度都要变为 \(1\),形成环(回路),所以我们可以先求出原图中每个点的度数(自环度数只 \(+1\)\(du_i\),枚举中心点,对每个去掉中心点的图按照回路的模型求最大匹配。

考虑求修改次数:

  1. 为了满足中心点 \(x\) 的约束,对于每个中心点,我们都需要 \(2n − 1 − du_x\) 次操作(因为没有重边)。
  2. 求出最大匹配 \(p\) 后,把没被匹配的边删掉,需要 \(m − du_x − p\) 次操作;把要加的边加上,需要 \(n − 1 − p\) 次操作。

答案为 \(\min\limits_{x\in V}\{3n + m − 2 \times du_x − 2p − 2\}\)


方格取数问题

经典问题:最小割 = 最大流。

将网格黑白染色,每个点向四周连边,流量为 \(INF\),白点向 \(S\) 连流量为其权值的边,同理黑点也向 \(T\) 连流量为其权值的边,答案即为所有点权值和 - 最小割(最大流)。

晚上

长脖子鹿放置

发现每个点和它能到的格子的行奇偶性不同,于是按照行染色,然后答案就是二分图最大独立集。

8.4

上午

英语暑假作业 8 & 语文暑假作业 7~8


[SDOI2017]新生舞会

01 分数规划 + 费用流。

About 01 分数规划:

问题一般是要求 \(\frac{\sum a_i\times w_i}{\sum b_i\times w_i}\)\(w_i\) 是个 0/1 变量)的最大 / 最小值。

以求最大值为例,我们可以二分一个 \(mid\),接下来推式子:

\[\begin{aligned} \frac{\sum a_i\times w_i}{\sum b_i\times w_i}&>mid\\ \sum a_i\times w_i-mid\times\sum b_i\times w_i&>0\\ \sum w_i\times(a_i-mid\times b_i)&>0\\ \end{aligned}\]

然后直接将每个物品的权值变为 \(a_i-mid\times b_i\) 看最大值是否大于 \(1\) 即可。

这道题中,我们可以二分 \(mid\),然后更改权值跑一遍二分图最大权匹配(最大费用最大流),看最大费用是否为正数。

下午

【模板】2-SAT 问题

2-SAT 是一个经典问题,可以使用 Tarjan 解决。

对于每个变量 \(i\),我们建立两个点:\(i\)\(i + n\), 分别表示变量 \(i\)true 和取 false

对于要求 \((a\lor b)\),转换为 \(\lnot a \to b\land \lnot b \to a\)

对于这个式子,可以理解为:「若 \(a\) 假则 \(b\) 必真,若 \(b\) 假则 \(a\) 必真」。

考虑节点 \(i\)\(i + n\) 在图中的关系。若它们互相可达,即在同一个强连通分量中,则说明在赋值限制下,它们代表的一对互斥取值会同时被取到,则不存在一组合法的赋值方案。

否则,说明有解,考虑如何构造一组合法解。

首先,对建出的图进行缩点得到一个 DAG。

考虑节点 \(i\)\(i + n\) 所在强连通分量的拓扑关系:

  • 若两分量不连通,则 \(x_i\) 取任意值(真或假)。
  • 否则只能取属于拓扑序较大的分量的值。因为若取拓扑序较小的值,可以根据逻辑关系推出取另一个值也是同时发生的。

Note:Tarjan 得到的强连通分量编号是拓扑序的 逆序


CF891C Envy

同一张图上的最小生成树的性质:

  1. 对于任意权值的边,所有最小生成树中这个权值的边的数量是一定的;
  2. 对于任意正确加边方案,加完小于某权值的所有边后图的连通性是一样的。

因此我们将询问离线,按照边权存储好,从小到大扫描每个边权,先将边权小于它的边加进并查集中,然后尝试加入一组询问中同样边权的边,如果成环则答案为 NO。可以使用可撤销并查集,但这个时候不能路径压缩只能按秩合并。

具体实现可以看代码理解。

代码

8.5

上午

CF1468A LaIS

好题。

不难发现一个合法的序列一定是在一个非严格递增子序列两两之间插入一个比左边的数大的数。

考虑设 \(dp_i\) 表示以 \(i\) 结尾的 LaIS 最长长度。

转移:\(dp_i=\max\limits_{1\le j<i,a_j\le a_i}\{dp_j+1+[\text{MAX}(j+1,i-1)\ge a_j]\}\)

因为 \(\text{MAX}(j+1,i-1)\) 随着 \(i\) 的增大而不降,所以对于每一个 \(i\),二分一个最小的 \(res\) 满足 \(\text{MAX}(i+1,res-1)\ge a_i\),然后用一个 vector 存储 \(res+1=j\) 的所有可能的 \(i\)

转移的时候用一棵值域线段树维护 dp 值,在 vector 中的数 \(+1\) 即可。

具体实现细节可见 代码

下午

[POI2008]POD-Subdivision of Kingdom

直接 dfs 枚举每个点在哪个集合中,顺便算一下贡献即可。


[NOI Online #2 入门组] 建设城市

对于 \(x\le n,y>n\)\(x,y\le n\)\(x,y>n\) 的情况分开讨论,然后隔板法直接计数即可。

8.6

上午

考试。

T1 不就是赛道修建搬过来?老套路二分 + multiset 直接写,要注意一些细节。

T2 筛出质数后前缀和,查询时二分即可。

T3 没怎么看。

T4 写了 50 暴力。

最后没挂分,100 + 100 + 0 + 50 = 250。

下午

改题。

T1 原题:[USACO20FEB]Delegation P

T4 是一道巧妙的树形 DP 题(link):

  • \(cnt_i\) 表示以 \(i\) 为一个端点的向下的路径条数,\(sum_i\) 表示以 \(i\) 为一个端点的向下的路径权值和。

  • 转移时可以分 \(u\) 是不是路径的一个端点转移,具体直接看代码。

T3 递归题,题解写的很详细,直接上链接:link

8.7

全天

Tony102《树上问题》专题讲课。

8.8

上午

第三届“图灵杯”趣味网络邀请赛。

中级组前两题都很简单,T1 直接栈模拟,T2 可以发现有枚举下界然后直接枚举即可。

T3 是一个贪心,考虑交换相邻两项的贡献差,然后按照 \(\frac{d}{k}\) 从大到小排序即可。注意 \(\sum d<0\) 的时候 \(d\) 要取相反数。

T4 ds 题。

8.9

上午

联考 Day1。

T1 实际上是一个 sb 题。。在 zyf 的提示下才做出来。。只需要考虑 \(a_i=b_i\) 的情况。

T2 写了 60 暴力 DP + 暴力矩乘挂成 0 了???把 bool 数组当成 int 用我也是没谁了。

T3 暴力 20 写挂。

T4 暴力 DP 25。

预估得分:100 + 60 + 20 + 25 = 205。

实际得分:100 + 0 + 0 + 25 = 125。

下午

T2 sb 容斥 + 矩乘。主要是要想到容斥哪些点不选。

矩乘要注意乘的到底是啥。。。

T3 nb 构造。

先离散化,然后对于每个连通块分开考虑。算出每个点在连通块中的相对 \(dep\),并查集处理一个节点有多个 \(k\) 级祖先的情况。

具体的,考虑按深度从大到小加入点和边,并用并查集维护当前每个连通块里最小的 \(dep\) 。如果 merge 两个不同的连通块时这两个连通块里最小的 \(dep\) 相等,就出现了不合法的情况。

T4 多项式恶心题 \(\texttt{/tuu}\)

晚上

Codeforces Round #737 (Div. 2)

补题进度:5 / 5

垃圾场,只过了 ABC 罚时还那么多。。。\(\texttt{/tuu}\)

A:容易发现把最大的单独拿出来放一组、其它的另一组答案最大。

B:看错题了。。离散化后判断相邻两个编号是不是连续即可。。

C:

分类讨论好题。

首先从高到低按位处理。

考虑按照 \(n\) 的奇偶性分类讨论(依据:当 \(n\) 为奇数时,若 \(\&=1\),那么 \(\oplus=1\);当 \(n\) 为偶数时,若 \(\&=1\),那么 \(\oplus=0\)):

  • \(n\) 为奇数时,若要满足题目条件,那么只可能 \(\&=1\)\(\oplus=1\)\(\&=0\)\(\oplus=0\)
    就相当于这一位上 \(n\) 个数字要么全是 \(1\),要么就有偶数个为 \(1\)。每一位方案数固定,是 \(1+2^{n-1}\)
    因为每一位选 \(0/1\) 的总方案数为 \(2^n\),其中奇数个 \(1\) 和偶数个 \(1\) 各占一半,那么选偶数个 \(1\) 的方案数就是 \(2^{n-1}\)
    所以答案就是 \((2^{n-1}+1)^k\)
  • \(n\) 为偶数时,要满足条件有两种方法:
    • \(\&=1\)\(\oplus=0\),这 \(n\) 个数这一位全部为 \(1\),那么以后的每一位就都可以随便选。
      假设枚举到了第 \(i\) 位,那么以后的方案数就是 \((2^{i-1})^n\)
    • \(\&=0\)\(\oplus=0\)。要选偶数个 \(1\),容易发现方案数就是 \(2^{n-1}-1\),原理和上面相同,只不过要减去全选的 \(1\) 个方案。

具体实现细节可参考代码:

for (int i = (pw[0] = 1); i <= 200000; i+=1) pw[i] = 1ll * pw[i - 1] * 2 % mod;
DC
{
    n = gi <int> (), k = gi <int> ();
    if (!k) {puts("1"); continue;}
    if (n & 1) printf("%lld\n", qpow(pw[n - 1] + 1, k));
    else
    {
        int ans = 0, res = 1;
        for (int i = k; i >= 1; i-=1)
        {
            ans = (ans + 1ll * res * qpow(pw[i - 1], n) % mod) % mod;
            res = 1ll * res * ((pw[n - 1] + mod - 1) % mod) % mod;
        }
        printf("%lld\n", (ans + res) % mod);
    }
}
return 0;

D:线段树无聊题。

先对区间离散化。然后考虑暴力 DP:\(f_i\) 表示前 \(i\) 行最多保留多少个,转移就是 \(f_i=\max\{f_k+1\}\)\(k\) 就是至少有 \(1\) 位同为 1 的行的编号。

我们考虑维护一棵线段树,线段树上每个节点代表能从这个位置转移过来的 \(f_i\)\(\max\),然后枚举行,每次转移直接在线段树上这一行为 1 的区间内取 \(\max\) 即可。

具体实现需要在线段树上维护最大值的位置,可能比较痛苦。

代码

E:无聊的交互题。不想写。

\(\text{Rating Change}\)\(2040\to 1995\)\(-45\)

8.10

上午

[GXOI/GZOI2019]旧词

容易联想到 [LNOI2014]LCA 那道题。

我们考虑 \(dep_{\text{LCA}(x,y)}\) 的另一种表达方式:将 \(x\) 到根的路径上每个点权值 \(+1\),然后询问 \(y\) 到根的路径上的权值和。

那一道题直接差分一下按照询问右端点排序直接做就行了。

这一题中,我们考虑引入一个差分数组表示 \(dep_{i}^k-(dep_i-1)^k\)。然后在线段树上直接修改即可。具体可参考 代码 或洛谷题解区。

[JLOI2016/SHOI2016]侦察守卫

一道很 nb 的 dp 题。

用到了一个技巧:状态互补。

\(f_{u,i}\) 表示 \(u\) 的子树中的关键点都被覆盖,且往上至少还能覆盖 \(i\) 层的最小代价,\(g_{u,i}\) 表示 \(u\) 子树内向下至少 \(i\) 层(\(u\) 节点自己算第 \(1\) 层)都没有被覆盖的最小代价。

要设置第一个状态的原因是可能出现子树间相互覆盖的情况,第二个状态设置 有点迷

转移的话,假设 \(v\)\(u\) 当前枚举到的子节点,那么 \(f_{u,i}=\min\{f_{u,i}+g_{v,i}, g_{u,i+1}+f_{v,i+1}\}\)\(g_{u,i}=\sum g_{v,i-1}\)。其核心是用前几个儿子已经得出的 \(f_{u,i}\) 去覆盖 \(v\),或者用 \(v\) 覆盖 \(u\)

然后注意 \(f\) 要求一遍后缀最小值,\(g\) 要求前缀最小值。

转移顺序要先更新 \(f\) 再更新 \(g\)

代码

下午

【模板】扫描线

扫描线就是从下往上扫描,并用线段树维护当前这条线段的覆盖情况。

[NOI2015] 寿司晚宴

容易发现 \(500\) 以内每个数最多只会有一个 \(\ge 23\) 的质因子,因此我们把这个大质因子单独拿出来排序做 dp。

\(dp_{s1,s2}\) 表示小 G 选的小质因子集合为 \(s1\),小 W 选的小质因子集合为 \(s2\) 的方案数。

把每个数的大质因子拿出来从小到大排序,对于大质因子相同的一串数再单独拿出来做一个 DP:

\(f1_{s1, s2}\)\(f2_{s1, s2}\),代表的含义同上面的 \(dp\) 数组,只不过 \(f1\) 表示这一个大质因子只能小 G 选,\(f2\) 表示只能小 W 选。

做完这一个大质因子后用 \(f1_{s1,s2}+f2_{s1,s2}-dp_{s1,s2}\) 来更新 \(dp_{s1,s2}\),因为可能这个大质因子两个人都不选。

参考代码

posted @ 2021-07-30 22:17  csxsi  阅读(8)  评论(0)    收藏  举报