2022.3

ますます多くの野菜,どうすればいいの?????

这个月比较摸(因为回学校上课了)

同样只是挑有意思的题写

3.1

T2

给你一个字符串 \(S\),求字典序第 \(n\) 小的包含 \(S\) 的字符串。

\(|S|\leq 1000,n\leq 10^{18}\)

建出 KMP 自动机然后在上面 DP,\(f_{i,j}\) 表示填到第 \(i\) 位,自动机上走到节点 \(j\) 的方案数,转移就是枚举当前位填什么字符,最后试填法求答案。

复杂度 \(O(|S|^2|\Sigma|)\)\(\Sigma\) 为字符集。

3.4

T1,T2 都是普及组小朋友做的题

T3

给你一个 \(n\) 个点 \(m\) 条边的有向图,一条路径的权值是经过的前 \(k\) 大的边权之和,求最短路。

\(n,k\leq 1000, m \leq 2000\)

先枚举第 \(k\) 大的边权 \(x\),我们将所有边的边权都减去 \(x\)(并与 \(0\)\(\max\))。
然后直接在这张图上跑 dijkstra,把跑出的最短路加上 \(x\times k\) 作为答案即可。

想一想就发现这个正确性很对。

好像也很简单,但我还是没做出来,怎么回事呢?

3.5

T2 是非常好的构造题,T3 是很无聊的根号题(把两种询问分别分块,还要用到 bitset 求 DAG 可达性,经典的分块卡空间做法)。

T1

对于偏序集 \((D(n),|)\),其中 \(D(n)\)\(n\) 的正约数集合,我们要求它的最长反链。

设正整数 \(n=\prod_{i=1}^k p_i^{\alpha_i}\),其中 \(p_i\) 为互不相同的质数,\(\alpha_i\in \mathbb{N}_{+}\)。我们记 \(\deg(n)=\sum_{i=1}^{k}\alpha_i\)\(n\) 的度。

有一个结论就是,考虑集合 \(U=\{d|\deg(d)=\lfloor m/2 \rfloor,d|n\}\),那么,\(U\) 就是一个最长反链的构造。

下面给出证明。

有空再写

3.7

T1 又是构造题,T3 是及其暴力的状压。

T2

好题

题意

给你一个由 rgb 三种字符组成的字符串 \(s\),进行 \(m\) 次变换,每次变换对于所有 \(i\)\(s_i\) 变为 \(f(s_i,s_{(i+1)\bmod n})\)\(f(c_1,c_2)\) 定义为,若 \(c_1=c_2\)\(f(c_1,c_2)=c_1\),否则为 rgb 中不是 \(c_1\)\(c_2\) 的那个。求最终字符串。

\(m\leq 10^{18}\)

rgb 看成 \(0,1,2\),则有 \(f(a,b)=2\times(a+b)\bmod3\)

考虑像 [AGC043B] 123 Triangle 那道题去推最初每个位置对最终位置的贡献,是一个组合数的形式,记 \(s_{m,i}\) 为第 \(m\) 次操作后位置 \(i\) 的值

\[s_{m,i}=\left(2^m\sum\limits_{j=0}^m\dbinom{m}{j}s_{0,(i+j)\bmod n}\right)\bmod 3 \]

因为是 \(\bmod 3\),所以考虑 Lucas 定理,我们发现当 \(m=3^k,k\in \mathbb{N}\) 时,只有 \(j=0\)\(j=m\) 时组合数才不为 \(0\),所以当 \(m\)\(3\) 的次幂时,有

\[s_{m,i}=-\left(s_{0,i}+s_{0,(i+m)\bmod n}\right) \bmod 3 \]

我们把 \(m\) 拆成 \(3\) 的次幂,每次 \(O(n)\) 计算即可,总复杂度 \(O(n\log m)\)

3.8

T1

Codeforces Round #775

这场 D,E,F 都很 amazing 啊

D 学到了线段树的奇怪打标记方法,懒标记表示左边对右边的贡献。

E Kruskal 最小生成树,启发式合并好题,大致思路很好想,但很多细节要仔细想清楚

F my first *3500!也是好题,要用到边三联通分量那个做法作为前置知识,想了两天才想懂,有空我去写个题解

3.11

摸了,耶!

3.12

接着摸,耶!

3.14

T1

T2

T3

3.15

T1

题目很容易转化成,给你一个立方体,其中一些点是障碍点,对每个点求包含它的子立方体个数,要求子立方体中不含障碍点。

先容斥一下,求出 \(f_{t,i,j,k}\) 表示 \((i,j,k)\)\(t\) 方向那个区域中的合法子立方体数量(\(t\) 的取值从 \(1\)\(8\) 分别表示 \(8\) 个方向)。现在,对于一个点 \((i,j,k)\) 通过 \(f\) 就可以容斥出不经过该点的合法立方体数量(这个式子总共 \(26\) 项),用总方案数去减就是包含该点的数量。

现在求 \(f\),如果是二维怎么做?想到 [GXOI/GZOI2019]与或和,显然可以单调栈 \(O(n^2)\) 求出。加上第三维,就 \(O(n^2)\) 暴力枚举第三维上的每个子区间,该子区间长度为 \(d\) 那就是把厚度为 \(d\) 的这一厚层中的障碍点都放到一层上,让后按二维做法做即可。总复杂度 \(O(n^4)\)。不过由于计算 \(8\) 个方向再加上单调栈的常数,并没有比 \(O(n^5)\) 做法表现好很多。

T2

题意

数轴上有一些黑白区间,一部分区间已经被指定了颜色,你要指定未染色区间的颜色,使得数轴上对于每个点,覆盖他的黑区间个数和白区间个数差的绝对值小于等于 \(1\)

这个建图真是太妙了啊啊啊啊啊啊啊啊啊

离散化之后,对于一个区间 \([l,r]\),把它看成从 \(l\)\(r\) 连一条有向边,染色就是给边定向。对于奇度数的点,我们把它们依次连到一起,然后就变成了欧拉回路。因为对于欧拉回路,覆盖在一个点上所有边朝两个方向的数量相等,除去为了处理奇度数点连的边,绝对值之差也不会超过 \(1\)

然后就是混合图求欧拉回路(应该很经典吧,但我第一次听说这个/qd)

做法:网络流

  1. 将所有无向边随意定向

  2. 计算每个点的入度和出度,如果入度和出度奇偶性不同,返回无解

  3. 把所有入度大于出度的点向汇点连一条容量为 \((入度-出度)/2\) 的边,所有出度大于入度的点从源点连一条容量为 \((出度-入度)/2\) 的边,原图中的边依然保留。

  4. 跑最大流,如果源点连出的边没有全部满流,返回无解。否则,将所有有流量的边反向,就是构造出的答案

正确性显然

T3

这个题真的

题意

一棵有边权的树,要求用最小的代价遍历这棵树。有 \(m\) 条额外边,第 \(i\) 条额外边的边权为 \(a_i\),对于所有的 \(K\in [0,m]\),计算在前 \(K\) 条额外边中选一些加入后遍历树边的最小代价。

\(n,m\leq 10^5\)

容易发现的是,如果不加额外边,每条边都要恰好经过两次,加入一条额外边 \((x,y)\),相当于原树上 \(x\)\(y\) 之间路径上的边只需经过一次。

记原树中所有边权和为 \(sum\)\(f_i\) 表示在树上选 \(i\) 条不相交路径的最长长度。将 \(a_1\)\(a_K\) 排序后,记前缀和为 \(s\)。那么,加 \(i\) 条额外边的答案就是 \(ans_i=2\times sum-f_i+s_i\)稍微想一想就发现\(s\) 是下凸的,\(f\) 是上凸的,那么 \(ans\) 就是下凸的(凸函数加凸函数仍然是凸的)。如果我们用平衡树维护 \(a\) 的话,就可以直接在平衡树上二分出最小的 \(ans\)

那么接下来就是求 \(f\) 了,我们可以考虑一种反悔贪心策略,我们每次求出树上的直径,然后把直径上所有边权变为相反数,再加一条路径的时候就再次求出直径,如果经过了之前经过的取反的边,实际上就相当于把重复部分的贡献减去了,两条相交路径除去重复部分后,就又拼成了两条不相交的路径,重复的部分就被反悔掉了(这个思路真是太神了)。

现在我们只需要一种数据结构,支持一下两个操作:

  1. 将树上一条链上的边权变为相反数

  2. 求树的直径

这个做法好像就比较多了(?),比如 LCT 之类的,但我只看懂了一种

首先对每个边建点,边权放到点上,再对整棵树进行三度化,然后轻重链剖分(上一步的三度化保证了这时每个点最多只有一个轻儿子)。

考虑如何维护直径,注意到一条路径会经过若干条重链,但这其中有且仅有一条重链,使该路径形如:从 \(u\) 的轻儿子走到 \(u\),在重链上从 \(u\) 走到 \(v\),从 \(v\) 的轻儿子下去(这种情况可能退化,即 \(u\)\(v\) 可以重合,也可以不从轻儿子走下去,但维护起来是不影响的)。

用数据结构维护每条重链,具体地,对于数据结构上代表 \([l,r]\) 的节点,维护四个信息,\(l\)\(r\) 的点权和,从左边过来再在 \([l,r]\) 中走轻儿子下去的最大值,类似的从右边过来的最大值,还有区间的答案,pushup 的方式类似区间最大子段和。因为还有修改操作,所以以上信息都要维护两份,分别表示现在的点权的值以及点权取相反数后的值。修改的时候直接 swap 两者即可,区间修改直接打懒标记就可以了。

为了做到总复杂度一个 \(\log\),我们采用全局平衡二叉树维护轻重链剖分。(应该是可以做到一个 \(\log\) 的,但因为我的实现要把每条重链的答案塞到 set 里维护全局答案,每次经过维护重链的一个 BST 的根都要更新 set 中的值,结果好像还是两个 \(\log\)

总之,这道题就做完了,总复杂是 \(O(n\log n)\)\(O(n\log^2 n)\),思路很清晰,但写代码强烈建议在脑子清醒的时候写。

3.17

今天的题是我们去年在北京组的题,竟然真做模拟赛了 233333

T1

题面真是太眼熟了(hxx 的题)

来源 CF1083F

很好的分块

T2

zzz 的题,好像是 Atcoder 的题,但找不到原题了

这个原根用的挺妙的,有空写一下

T3

记忆化搜索好(?)题,各种分类讨论码了 5.8K /cy

3.18

T1

T2

T3

3.21

T1

这个题的 nb 之处就是一个 trick,高维或的前缀和的压位优化。把正常的 \(O(n2^n)\) 优化到 \(O(2^n+(n-6)2^{n-6})\)(用 \(\text{unsigned long long}\)\(2^6\) 位)

T2

给定长度为 \(n\) 的排列 \(a\)\(q\) 次询问 \([l,r]\),求 \(\sum_{i=l}^r\sum_{j=i+1}^rf(a_i,a_j)\)\(f(x,y)\) 定义如下:

  1. \(x=y\)\(f(x,y)=1\)
  2. \(x\not= y\)\(f(x,y)=f(x+y-|x-y|,|x-y|)+1\)
  3. 若无限循环,其值看作 \(0\)

\(n,q\leq 10^5\)

这个题的难点竟然就是看出这个 \(f\) 是什么东西。

首先这个函数计算过程中保持了 \(x+y\) 不变,所以 \(x+y\) 为奇数一定无限循环,计算过程中 \(\gcd(x,y)\) 也是不变的,所以我们把 \(x,y\) 都除以 \(\gcd\) 没有影响。所以 \(x,y\) 同为奇数,不妨设 \(x>y\),此时 \(y\times2,x-y\) 都是偶数。假设 \(y\times2\)\(x-y\) 有与 \(2\) 互质的不为 \(1\) 的公因数 \(k\),那么 \(k|y\) 并且 \(k|x-y\),推出 \(k|x\),这与 \(x\perp y\) 矛盾!所以 \(y\times 2\)\(x-y\)\(\gcd\) 就是 \(2\),就等价于求 \(f((x-y)/2,y)\)。由此得出 \(x,y\) 的和在计算过程中会不断除 \(2\),直到 \(x=y=1\) 或无限循环。

结论就是,当 \((x+y)/\gcd(x,y)=2^k\) 时,\(f(x,y)=k\),否则 \(f(x,y)=0\)

然后那个求和就很简单了,询问都离线下来从后往前扫一遍,用树状数组维护就可以做了。

3.28

T1

打开题面,交互题贴脸

其实挺简单的,还剩半个小时的时候会了,但因为要去做核酸就没写

T2

题意

给你一个序列,求把它划分成若干段的所有方案的各段 \(\operatorname{mex}\) 乘积之和。

\(n\leq 10^6\),时间限制 1s

显然的状态转移方程

\[f_i=\sum\limits_{j=0}^{i-1}f_j\times\operatorname{mex}\limits_{k=j+1}^{i}\{a_k\} \]

我们来看看,怎么在 \(i\) 变化的同时维护那个 \(\operatorname{mex}\)。首先我们发现这个 \(\operatorname{mex}\) 一定是单调不上升的,也就是一个一个的段,考虑加进来一个 \(a_i\),又发现只会改变 \(\operatorname{mex}\) 等于 \(a_i\) 的那部分值,也就是说,会将一个段分裂成若干小段(这部分很像 2.19 T1),总共只有 \(O(n)\) 次区间修改。

大致流程就是

每次找到 \(\operatorname{mex}\) 等于 \(a_i\) 的一段 \([l,r]\),然后求出 \(\operatorname{mex}\limits_{j=r}^{i}a_j\)(就是新的 \(\operatorname{mex}\) 值,这个可以线段树求),设它等于 \(x\),找到 \(r\) 前面第一个等于 \(x\) 的位置 \(j\),把 \([j+1,r]\)\(\operatorname{mex}\) 值都设为 \(x\),然后把 \(r\) 赋值为 \(j\),继续上面过程知道 \(l<r\)

至于怎么求区间 \(\operatorname{mex}\),考虑用权值线段树维护 \([1,i]\) 中每个树最后出现位置的最小值,然后在线段树上二分找到第一个最后出现位置小于 \(j\) 的值,就是 \([j,i]\)\(\operatorname{mex}\)

还有就是原序列中大于 \(n\) 的值没用,可以直接设成 \(n\),不用再离散化了,区间 \(\operatorname{mex}\) 都是以 \(i\) 为右端点的,不用写主席树了,找 \(r\) 前面第一个等于 \(x\) 的位置也是直接 \(O(1)\) 维护了,不用再用 vector 存下标再二分了,\(f\) 值再区间修改时直接算贡献就行了,不用再线段树维护了。

然而以上睿智写法全部出现在我的代码里/cy

T3

一个长度为 \(n\) 序列 \(a\),Alice 要把它重新排列后交给 Bob,Bob 可以不断交换相邻的互质的两个数,Alice 希望最后字典序最小,Bob 希望字典序最大,求最终序列。

\(n\leq 2000\)

对于 Bob 来说,不互质的两个数的相对位置是无法改变的,如果对于不互质的 \(a_i,a_j\ (i<j)\) 我们连一条从 \(i\)\(j\) 的边,得到一个 DAG,那么最终序列就是字典序最大的拓扑序。

现在问题就是 Alice 会怎么排列序列,也就是说,对于不互质的 \(a_i,a_j\) 我连一条 \(i\)\(j\) 间的无向边,现在要给无向边定向。

其实我们对这个无向图 dfs,对于 \(x\),每次选权值最小的点 \(y\) dfs 下去,连边 \((x,y)\),得到的图就是对于 Alice 最优的选择。

虽然这个感觉很对,但我还是觉得题解的做法更清楚一些

首先不同联通块之间肯定没有影响,最终把它们多路归并即可。而对于每个连通块,我们可以为它确定一个唯一的入度为零的点最为起点(选择权值最小的),这样 Bob 只能先选它。

确定这个点之后,我们可以把它相邻的点打上标记,然后删掉该点,原图变成若干连通块,对于每个连通块,我们在标记的点中选择最权值小的点最为起点,然后递归下去即可。

还有一个问题,如果得到所有联通块?边数是 \(O(n^2)\) 级别,无法接受。考虑优化建图,对于每个质数建一个点,每个数向它的所有质因子连边,这样边数降为 \(O(n\omega(a_i))\),而连通性不变,太棒了!

这样我们的复杂度就是 \(O(n\sqrt{a_i}/\ln a_i+n^2(\log n+\omega(a_i)))\) 前边那个是分解质因数的复杂度。

3.29

T1

终于,赛时切题了,泪目,不过只是个签到题

T2

给你一个边上有字符的树,\(m\) 个询问,每次询问给你一个字符串 \(s\),问树上存不存在一条路径上的字符串等于 \(s\)

\(n,\sum s\leq3\times 10^4\)

这就是个暴力题...

\(f_{x,j,k}\) 表示树上从下往上走到 \(x\),能否匹配 \(s_j\) 的长 \(k\) 的前缀,\(g_{x,j,k}\) 表示从 \(x\) 往下走,能否匹配 \(s_j\)\(k\) 的后缀,前后缀拼一下就是答案了。

这个 dp 状态数为 \(O(n\sum s)\),不过转移都可以 bitset 优化,也就能做到 \(O(\dfrac{n\sum s}{\omega})\)

不过这个东西写 dfs 会 MLE,要提前 dfs 一遍把拓扑序记录下来,然后用一个循环 dp。以后写题可以注意一下,卡时间和卡空间都可以试试这样把 dfs 改成循环。

T3

还不会...

3.31

T1

DP,笑死,根本不会 DP。

给定两边各 \(n\) 个点的二分图,左边的第 \(i\) 个点向右边的 \(1\)\(a_i\) 号点连边,求图中简单环(点不重复)数量。

\(n\leq5000\)

首先把 \(a\) 从小到大排序,然后考虑 DP。

\(f_{i,j,k}\) 表示左边前 \(i\) 个点,右边选了 \(j\) 个单点,连出了 \(k\) 条链(形如右-左-右-左-右这样的)的方案数。

考虑转移,我们可以从左侧的 \(i\) 连出两条边,可以把右边的两个单点或两个链或一个单点和一条链连起来,注意单点和单点连的方案数是 \(1\),但是单点和链的方案数是 \(2\),链和链连的方案数是 \(4\)

每次把 \(f_{i,0,1}\) 累加进答案即可。

但这么设计状态是 \(O(n^3)\) 的,于是我们考虑把 \(j\)\(k\) 两维合并成一维。

\(f_{i,j}\) 表示左边考虑到第 \(i\) 个点,右边有 \(j\) 个段(包括单点和链)。但这样不就没法统计 \(\times2\)\(\times4\) 的贡献了吗,其实是不影响的,对于 \(j\) 个单点和 \(k\) 个链,我们可以把 \(f_{i,j+k}\) 看成方案数乘上 \(2^k\),而转移时,\(f_{i,j}\) 转移到 \(f_{i,j-1}\) 直接成上 \(j\times(j-1)\) 的系数(两两配对再 \(\times2\)),这样如果连上的是两个单点,多乘了 \(2\),但也恰好多出了一条链,而如果连上的是两条链,少乘了 \(2\),但链的总数也少了一个,这样就保证始终是方案数 \(\times2^k\)。真是...太神奇了

所以最后转移就是

\[f_{i,j}\leftarrow \sum\limits_{k=0}^{a_i-a_{i-1}}\dbinom{a_i-a_{i-1}}{k}f_{i-1,j-k}\\ ans\leftarrow (f_{i,1}-a_i)/2\\ f_{i,j}\leftarrow j\times(j+1)\times f_{i,j+1} \]

第一步是加入 \(a_{i-1}\)\(a_{i}\) 这些单点,第三步就是选两段连起来。

复杂度就很显然的是 \(O(n^2)\) 了。

T2

找规律 + min25,笑死,连规律都找不到。

求有多少个正整数 \(k\) 满足:

  • \(1\leq k\leq n\)
  • \(a^2+b^2+k=c^2\) 成立且 \(a,b,c\) 构成等差数列的正整数 \((a,b,c)\) 有唯一解

\(n\leq 10^{11}\)

经过打表得到结论,\(k\) 满足条件当且仅当, \(k\) 为模 \(4\)\(3\) 的质数或 \(k=4p\)\(k=16p\)\(p\) 为奇质数)或 \(k=4\)\(k=16\)。其实有证明的只是看不懂

所以只要分别求出 \(n\) 以内模 \(4\)\(1\) 和模 \(4\)\(3\) 的质数的个数即可,这个 min_25 筛可以胜任。

我们只需要 min_25 中求 \(g\) 的过程,我们设 \(g_0\)\(g_1\) 分别为模 \(4\)\(1\)\(3\) 的值,然后按当前的质数模 \(4\) 等于几分类互相转移即可。

复杂度就是 min_25 的 \(O(\dfrac{n^{3/4}}{\log n})\) (如果我没记错的话)

T3

分治 + 线段树历史最值,笑死,根本没学过线段树历史最值。

给你 \(n\times n\) 的平面区域,有 \(m\) 次矩形加,\(q\) 次矩形询问最值,所有询问都在修改操作之后。

\(n,m\leq 5\times 10^4,q\leq 2\times 10^5\)

先考虑所有询问操作都是 \(x_1=1\),我们可以直接对 \(x\) 轴扫描线,线段树维护 \(y\) 轴,询问就是区间历史最大值。

然后分治,思路就很清晰了,对于分治区间 \([l,r]\),我们处理所有 \(x_1\leq mid\leq x_2\) 的询问,即从 \(mid\) 向两边做两次扫描线。

对于修改操作,如果它覆盖了当前分治区间,那就没必要下传下去,直接在线段树修改,不撤销它,然后递归下去,这样每个询问只会留在 \(O(\log n)\) 个区间上,保证了复杂度。总复杂度 \(O(q\log n+m\log^2n)\)

对于线段树的撤销操作,我用栈把所有经过的节点都记录下来,最后撤销,但常数似乎有点惨不忍睹,所以要卡常卡常卡常。

总之还是思路很好的题

三月份就这么过去了啊

posted @ 2022-03-22 21:10  iMya_nlgau  阅读(95)  评论(0编辑  收藏  举报