暑假训练记录(三)
序列
好题
LOJ 6490
发现咋做都不太行,考虑分治。
分治就是考虑左右两半区间的互相影响,对应到这个题就是跨越中间点的区间。
枚举一个端点之后可以看成对一个跨越中点的区间 chkmax,我以为这个比较不可做,因为假如枚举了左端点那么右端点在变化的过程中覆盖到的区间会变化,不能用简单的 chkmax 来描述。
为啥不行呢??仔细思考一下,因为我们钦定了区间跨过中点,你右端点变化,影响到的是右边区间的覆盖情况,跟我左边区间啥关系啊??
我们回归分治的本质,处理右边区间对左边区间的影响,那么右端点就可以简单地直接选取前缀和序列的最大值,对应到左区间上的影响就是 chkmax 一段后缀,可以简单用一个变量维护。对于右边的区间再做一遍即可。
CF585E
没看懂和序列有啥关系。。?
考察条件,发现 \(x\notin S\) 这个条件是不必要的。
于是我们可以这么搞:枚举 \(d=\gcd(S)\),式子就是:
前面一个括号是经典的迪利克雷后缀和之后再差分回来,后面一个用莫反之后也是迪利克雷前缀和形式。于是可以做到 \(O(V\log\log V)\)。
ABC262H
这个故事告诉我们不要看到 \(\max\) 就想容斥,说不定可以直接大力维护。。。
首先拿你喜欢的数据结构判判无解,顺便求出 \(v_i\) 表示第 \(i\) 个数的最大值。
限制条件,所谓一个区间的 \(\max=X\),就是说这个区间里所有数都 \(\leq X\),并且至少有一个数 \(=X\)。前者我们已经解决了,现在需要解决后者。发现 \(X\) 不相同的限制互不相干,那么我们把所有 \(v_i\) 相同的 \(i\) 和限制拎出来统一处理。
此时发现我们只关心一个数是不是等于 \(X\),所以可以设 \(f_{i,j}\) 表示填到第 \(i\) 个数,上一个 \(=X\) 的位置是 \(j\)。可以线段树优化。
复杂度 \(O(n\log n)\)。
CF2066D2
计数的主体是长为 \(m\) 的序列 \(a\)。需要满足:
- \(cnt_n=c\)。
- \(\forall i=1,2,\cdots,n,\text{s.t.} \sum_{j\leq i}[a_j\leq a_i]\leq c\)。
考察一个更简洁的充要条件。不难发现对于相同的 \(a_i\),只有最后面一个的限制有用,而这个限制是值域从小到大互相影响的。设 \(pos_i\) 为 \(i\) 这个值出现的最后位置,那么条件可以改写为:
不难发现这是充要的。所以可以 DP 设 \(f_{i,j}\) 为填了 \(1\sim i\)
的数,填了 \(j\) 个的方案数,转移时枚举 \(i\) 这个数填了几个即可。
括号序列
括号序列通用处理方法:建树、前缀和。
P7323
不妨把 \((x,y)\) 合法,看成一种二元关系。容易发现这个关系满足传递性,自反性。于是这个关系连成的边形成若干个团,也就是若干个等价类。
考虑最开始每个点都是孤立的,现在要把他们合并到不能合并为止。若存在一个等价类,其有两条类型相同的出/入边,那么可以将其连接的两个等价类合并。
考虑怎么快速找到像这样的东西,直接启发式合并维护即可。
P11236
考虑把值域的连续段合并成一个信息统一维护。合并的时候如果形成了谷就立即合并上来。如果出现奇数长度就掰成两半。线段树维护可以做到 \(O(nV\log n)\)。
CF1503F
考虑怎么刻画一个匹配方案。可以横着画 \(n\) 个点出来。对于一个顺序,若牌 \(i,j\) 在正面是匹配的,那就在这些点的上面给他连一个边,如果是在背面匹配,那就在下面连边。
方案合法的条件就是没有两条边是“交叉”的,也就是说这个图是一个
“平面图”。但是这不完全等价。容易发现每个点正好连了两条边,那么这个图是由若干个环构成的,而且必定是上下交错。
考虑找到一个较快的方法判定一个图是否合法。我们发现一个合法的环的端点一定存在一个形如上面 \(a\to d\),下面 \(d\to c\),再上面 \(c\to b\),满足 \(a<b<c<d\)。或是上下颠倒。这样我们可以把这三条边和 \(c,d\) 两个点删掉,用一条 \(a\to b\) 来替代。如果合法最后一定形如若干个二元环。
方案可以在判定的过程中构造。
想不明白了,td。
CF1685C
用前缀和刻画。考虑一个反转之后会怎么变化。把区间里的折线按照两个端点的中点位置中心对称。
观察到一定可以用不超过两次操作将序列变为合法。只要选定全局 \(\max\) 然后让其对开头和结尾各操作一次即可。
那么问题就变成了怎么判断能否只用一次操作。容易发现我们选的中心对成点越高越好,所以只要选所有负数位置的前面和后面的 \(\max\) 位置来尝试就行了。
CF1485D
跟上个题一样考虑前缀和之后再刻画操作。不难发现是左右对称。而且可以发现这个操作是可逆的,也就是说能到达的状态类似若干个等价类。
有等价类,考虑找不变量。考虑所有前缀和值构成的可重集,发现在操作过程中是不变的 \(S\)。进一步,考虑所有相邻位置的前缀和构成的对 \((s_i,s_{i+1})\) 构成的集合 \(T\),容易发现这个也是不变的。
现在断言,所有的能到达的结果集合就是满足 \(T\) 相等的所有状态。必要性显然,上面已经说明了,现在来证明充分性。
考虑建出一个图,把不同的 \(s_i\) 的值当作点,\((s_i,s_{i+1})\) 当作边,那么一个状态就是一条这个图上的欧拉路径。
考虑操作一次对这个路径的影响是什么,就是选一个环来翻转上面边的方向。考虑这个图上的任何一个欧拉路径,与原来的欧拉路径第一个不同的位置。设原路径在这个点往 \(x\) 这条边走,而选定的这条路径是往 \(y\) 走。那么原路径一定有一个从 \(x\) 出发,再从 \(y\) 走进来的环,翻转这个环即可让这两条路径上的这条边相同。如此归纳下去不难发现一定可以达到所有状态。
那现在只要求这个图上的字典序最小欧拉路径,贪心即可。
排列
一类常见的关于排列的计数问题是,贡献是关于排列相邻的两个值的。此时我们可以按照一个钦定好的顺序来往排列中插入元素,这样有时能起到解耦的效果。
数数
题来自云浅。
CF995F
旧题新做。考虑二项式反演。先树形 DP 求出 \(g_i\) 表示至多使用 \(i\) 种数的方案数,然后反演出恰好,可以计算。
ABC242H
设 \(E_i\) 为第 \(i\) 个格子被覆盖的期望时间,那么答案即为 \(\max_i E_i\)。
min-max 容斥一下,变成算:
而 \(\min_{i\in S}E_i\) 就是,区间总数除以包含 \(S\) 里任何一个点的区间个数。
考虑设 \(f_{i,0/1,j}\) 表示前 \(i\) 个点,选的点的个数的奇偶性,被 \(j\) 个区间包含的方案数。可以直接 DP。复杂度 \(O(n^2m)\)。
LOJ3395
考虑一个排列能被 \(k\) 步之内操作出来的充要条件。就是存在一个长度为 \(n-k\) 的连续上升子区间。
对 \(k=1\sim n\) 计数满足存在一个长为 \(k\) 的连续上升子区间的排列数。可以容斥一下变成所有连续上升子区间长度都 \(<k\) 的排列数。
考虑直接确定 \(n-1\) 个 \((p_i,p_{i+1})\) 对的大小关系。就是一个长为 \(n-1\) 的由 < 和 > 构成的字符串,那么这个字符串要满足连续的 < 个数 \(<k-1\)。考虑怎么对一个字符串计算满足这个大小关系的排列个数。对 > 的一个子集容斥,强制令其变为 <,这样方案数是多重组合数。
考虑不枚举字符串,直接枚举字符串中未被钦定的 > 集合,这样会把原序列分成若干段。要求每一段内部不能有长度为 \(k-1\) 的 < 连续段,且每出现一次 > 就要乘上 \((-1)\) 的系数。容易发现这个东西只跟段长有关,可以先处理出来,记作 \(g_i\)。
那要算出答案就可以再设一个 DP。\(f_i\) 来表示长为 \(n\) 的排列的方案数。转移时钦定一个 > 不被选。做一次是 \(O(n^2)\) 的。过不了。
但是打表发现对于一个 \(k\),\(g_i\) 只有 \(O(\frac{n}{k})\) 项非零。所以可以在 \(O(n^2\log n)\) 的时间内做 \(n\) 次 DP。
为啥呢,考虑写出 \(g\) 的生成函数:
摆了。
ABC236H
考虑容斥钦定一些 \(a_i\) 相等,但是这样至少是 \(O(2^{\frac{m(m-1)}{2}})\) 的。过不了。考虑钦定形成的连通块情况才会实际影响答案,不妨设 \(f_S\) 表示 \(S\) 内的联通情况已经确定,每次转移枚举一个集合作为连通块加入:
推导一下 \(g\)。这个问题与连通性相关,所以考虑容斥。设 \(h_n\) 为 \(n\) 个点的无向图的系数之和。容易得到 \(h_n=[n=1]\)。那么:
结合 \(g_1=1\),可以得到 \(g_n=(-1)^{n+1}(n-1)!\)。
直接半半在线子集卷积即可做到 \(O(n^22^n)\)。
P10591
考虑斯特林反演。设 \(f_i\) 表示钦定有 \(i\) 个连通块的方案数,\(g_i\) 表示恰好,则:
反演得到:
所求即为:
至于 \(f_i\) 怎么求,直接暴力贝尔数枚举划分方案,然后钦定集合之间不能连边,方案数可以用线性基统计。
P3447
考虑一个数 \(\leq m\) 的条件,就是有一个长度为 \(t\) 的 LCP 跟 \(m\) 相同,后面的随便选。而最高位 \(\leq t\) 的 \(a_i\) 可以随便选,因为无论如何都能被消除。所以可以枚举所有数的 \(\max t\) 然后 DP 做到 \(O(n\log V)\)。
P10104
首先考虑这样一个问题:P3447。
对这个题,要求异或和 \(=C\),那么可以额外加入一个新点 \(a_i=C\),再减去新点 \(a_i=C-1\) 的方案。
然后可以容斥钦定连通块内相等。容斥系数设为 \(f_S\),相当于算子图内连通的情况。考虑容斥,设 \(g_S\) 表示 \(S\) 内随便的方案数,有 \(g_S=[E_S=0]\),转移:
td
YDRS005E
考虑如何判断一个染色方案合法,可以直接状压 \(f_{i,S}\) 表示到第 \(i\) 列,还没被覆盖的白色格子集合为 \(S\)。
考虑如何计数。还是按列填,但是状态记录的是 \(S\) 的集合(也就是一个簇),其中 \(S\) 表示当前染色方案能到达的第 \(i\) 列的覆盖状态。
此时打表一下,发现状态数很少!?强强?!
发现如果 \(S\) 中存在两个连续的 \(1\),那么这种状态是没用的,因为可以通过放两个竖着的来代替。剪枝之后打表一下,发现状态数只有 \(169\) !!??强强??!!
P3581
考虑按值从小到大插入每个数,不难发现我们只需要记录 \(i-1,i-2,i-3\) 之间的位置关系即可。直接 DP。
P9083
建笛卡尔树。设 \(f_u\) 表示 \(u\) 子树内全部删完需要的步数,容易得到:
对着这个 DP 即可。
P10547
考虑如何计算 \(f(p)\)。首先:
因为一次花费 \(x\) 的操作最多将其减去 \(2x\)。
然后猜测这能取到下界。考虑证明。即证明一定存在 \(x<y\) 满足:
td。。
ARC163D
\(O(n^5)\) 说过了。\(O(n^4)\) 的话直接不确定连通块内的边,最后统计答案的时候再搞就行。
ARC013D
可以拿二维平面折线刻画一下,但是会算重。但是直接钦定一下必须碰到边界就行了。
ABC241H
考虑生成函数。直接写出,答案为:
其中前面一项可以暴力 \(O(2^n)\) 做,考虑求后面一项,使用部分分式法,设:
然后把 \(z=\frac{1}{a_i}(i=1,2,3,\cdots,n)\) 代入,可以求得 \(p_i\)。
P4365
拆贡献:
可以设 \(f_{u,x,i}\) 表示以 \(u\) 为根的连通块,有 \(i\) 个数 \(\leq x\) 的连通块个数,转移:
可以看到是关于最后一维的一个加法卷积。可以看成一个多项式然后对应点值相乘,最后再插值回来。此时要维护:
如果按照 \(x\) 这一维来考虑,就可以线段树维护,更进一步还可以线段树合并维护,真是太厉害了!
可以加强 \(w\) 到 \(10^9\),只要离散化一下就行了,非常厉害!
DS
降维
许多 DS 问题形如数点和偏序。此时问题的维数以及性质(可差分性之类)影响了这类问题的时间复杂度。而不少问题的维之间是有相互关联性的,这可以让我们据此来对问题来降维。
TEST_73
给定一棵树,点和边都有编号。每次询问 \(l,r\),问保留编号为 \([l,r]\) 内的点和边,有多少个点连通块。
考虑点减边。现在要统计有多少条边,设这条边为 \((u,v,w)\),那么要满足 \(u,v,w\in [l,r]\) 这三条限制。注意这三维有什么共同的特点,那就是查询的范围都一样。所以等价于 \(\max\{u,v,w\},\min\{u,v,w\}\in [l,r]\)。二维数点即可。1log。
未公开题目
给定 \(n\) 个区间 \([l,r]\),和 \(m\) 次查询。每次给定 \(l,r,k\),问有多少区间被 \([l,r]\) 包含且长度 \(\leq k\)。
不妨先在平面上画出来要查询的区域。因为区间长度跟区间左右端点关系很大,所以能在一个平面上表示出来。画出来之后是查一个等腰直角三角形的区域。考虑给这个三角形差分成 2-side,这样可以扫描线扫斜线,剩下的就是一维数点。可以做到 1log。
TEST_139
\(q\) 次操作。3-side 等腰直角三角形加和 4-side 矩形求和。
能差分先差分。三角形差分成左上方向的 2-side 三角形,矩形差分成右上方向的 2-side 矩形。
考虑一次查询,三角形对矩形有多少种不同的贡献形式。发现要么矩形包含三角形的一个角,要么三角形包含矩形的一个角。两种贡献都可以写成若干个信息二维数点。直接 CDQ 分治即可做到 2log。
P9061 弱化版
给定平面上 \(n\) 个点,每次操作:
- 给出 \(x,y\),将 \([0,x]:[0,y]\) 的点删除。
- 求一个 4-side 矩形和。
容易发现删除的轮廓线是一条右上-左下的折线。容斥之后变成了数折线之内与矩形的交的区域里的点数。给 4-side 矩形差分成左下的矩形。如果这个矩形被折线完全包含,就直接数点。否则继续容斥差分,变成分别数上面、右面,右上的点。右上一定没有被折线修改可以直接数。剩下两个是一维问题,可以直接维护。可能需要连续段均摊之类的东西先把修改的代价离线下来数点之类的东西。反正 1log。
P11721
首先这个题在时间维上建线段树。维护的信息相当于半群。
然后发现线段树一个节点上本质不同的标记一共有 \(O(len)\) 种,于是可以建出来一个类似归并树的结构。每次查询的时候在 \(O(\log q)\) 个节点上二分,可以做到 2log。
要做到 1log,考虑分散层叠。每个相邻的左边的线段树的根往右边放右边的长度个点进去,这样是 \(O(\log q+\log n)\) 一次查询。
树上问题
P4220
一个非常牛的结论是,我们总可以找出 \(8\) 个点,满足任何一个点 \(u\) 的 \(\operatorname{argmax}_v\{\operatorname{dis_1}(u,v)+\operatorname{dis}_2(u,v)+\operatorname{dis}_3(u,v)\}\) 都是这 \(8\) 个点之一。
那我们不知道这个结论,咋办???
考虑对第一棵树边分治,把分治割成的两个集合里的点分别标上黑色和白色。然后对这些点在第二棵树上建虚树,最后在这个虚树上 DP 维护第三棵树上的直径即可。
复杂度 \(O(n\log^2n)\)。
边分治
最大的好处是只需要考虑两个集合的合并,强强??!!??
但是会被菊花图卡掉。
考虑转成二叉树,把每个点的儿子用线段树的方式连一遍就行了,容易发现新增点数为 \(O(n)\)。
LOJ3399
设 \(f_S\) 为在 \(E\) 中的边集恰好为 \(S\) 的生成树个数,\(g_S\) 为超集的生成树个数,可以得到:
反演得到:
枚举 \(S\),答案为:
考虑组合意义,那就是选一个边集,贡献是在这个边集里选一条边的方案数,乘上每个连通块里面选一个点的方案数,除此之外每个连通块还有 \(n\) 的贡献。
直接 DP 即可。
LOJ3066
特殊性质是,每条路径都是一条链,此时直接启发式合并维护即可。
对于一般情况,若交路径为一条链,则直接在顶端统计即可。否则一定是两条 LCA 相同的路径交在一起。设为 \(x_i\to y_i\) 和 \(x_j\to y_j\),那么一定满足交路径为 \(\operatorname{LCA}(x_i,x_j)\to \operatorname{LCA}(y_i,y_j)\)。考虑枚举 \(\operatorname{LCA}(x_i,x_j)\),启发式合并维护满足这个的点对 \(i,j\)。考虑如何最大化路径长,那一定是 dfn 相邻的两个 \(y_i,y_j\) 贡献最大,直接维护即可。
这个问题告诉我们关于什么 LCA 什么虚树的问题,可以放到 dfn 上来考虑。
Prufer 序列
是建立了序列与有标号无根树之间的一个双射。
考虑把树转化成一个序列。每次选一个编号最小的叶子删掉,往序列的末尾加入这个叶子所连接的点,直到最后剩两个点一条边为止。容易发现树到序列形成一个单射。
考虑把序列还原成树。序列里没出现的数都是叶子节点,考虑维护当前叶子节点的集合。每次从集合里取出最小值,与序列的开头的数连上边。若当前是序列开头的数最后一次出现,则将其加入集合。最后把集合里剩下的两个点连边。容易发现序列到树形成一个单射。
容易发现序列与树形成一个双射。所以容易得到 \(n^{n-2}\)。
可以得到一个推论,连通块的之间的生成树个数为 \(n^{k-2}\prod_i s_i\)。
关于 prufer 序列有一个性质,就是一个点的出现次数为其度数 \(-1\)。
试看看:\(n\) 个左部点,\(m\) 个右部点的完全二分图的生成树计数。
考虑最后剩下的两个点,一定一个左一个右,也就是说左部点要删除 \(n-1\) 个,右部点要删除 \(m-1\) 个。也就是说左部点在序列中出现 \(m-1\) 次,右部点 \(n-1\) 次。
考虑 \(n^{m-1}\) 种左部点序列和 \(m^{n-1}\) 种右部点序列归并起来有多少种方案。不妨把这个图标号为 \(1\sim n\) 和 \(n+1\sim n+m\)。不难发现每次选哪一边是确定的,所以方案数就是 \(n^{m-1}m^{n-1}\)。
CF1433E
对于每个点,把经过这个点的火车按时间顺序排序。那么这个点要切换的就是不同儿子交界处。
分析一下可以得到,所有节点的交界次数之和是 \(O((n+q)\log n)\) 的,因为带权重链剖分之后,把轻儿子合并到重儿子上,最多会产生 \(O(轻儿子)\) 个新交界点。
于是直接维护即可。
P8990
考虑合法的充要条件,就是所有没点亮的点是一个连通块。可以点减边。
考虑贡献,也是点减边。在时间轴上建立一个线段树,维护两个变量 \(a,b\),要做的是区间加,查询全局 \(a=0\) 的 \(b\) 的和,可以直接维护。
思考题
众数杀手
一类关于区间绝对众数的问题。
首先枚举数,把 \(=x\) 的数变成 \(1\),剩下的数变成 \(-1\)。那么一个数是区间绝对众数当且仅当区间和 \(>0\)。现在我们想找出所有区间众数为 \(x\) 的区间。直接扫一遍是 \(O(n)\) 的,太慢了。慢在哪?慢在如果中间有很长一段 \(-1\) 那么这一段肯定没用。
考虑从左往右扫,给每个 \(1\) 标记其右边还没标记的第一个 \(-1\),再从右往左扫一遍。然后只考虑这些位置。容易证明这些位置之外的位置都不可能被包含进一个绝对众数为 \(x\) 的区间内。这样每次需要的数就是 \(O(cnt_x)\) 的。全部枚举一遍也才 \(O(n)\)。
精细实现可以做到 \(O(n)\)。
前 k 大问题
这种一般是构造一个转移图,使其转移边数不太多,并且转移满足权值按照顺序,并且每个状态都在图上。
常用的优化是,左儿子右兄弟,多叉树转二叉。
这种方法的本质是类 Dijkstra。
模拟赛
9.25
T1
给你 \(n\) 个区间,你可以花费 \(1\) 的代价将一个区间平移一个单位长度,给定 \(k\),问花费不超过 \(k\) 单位的情况下最后所有区间的交最长是多少。
\(n\leq 5\times 10^5,L_i,R_i\leq 10^9\)。
先二分答案。考虑判定。枚举最终线段在哪,考虑到只有最终线段端点穿过原线段的端点的时候答案才有可能变化,所以可以离散化出来所有区间的左右端点然后枚举,前缀和维护即可。\(O(n\log V)\)。
T2 P13345
如果确定了一个方案,那么每个人的取值范围是一段区间,而且要求这些区间互相不交,但是有一种特殊情况是两个区间的交为 \(1\),且编号较大的在下面。
继续观察,可以发现一个人最后的区间一定是包含这个人的和的,那么可以确定这些人的顺序了,设排序之后第 \(i\) 个人的真实成绩为 \(s_i\)。那么可以考虑一个 DP。设 \(f_{i,j}\) 为第 \(i\) 个人的上端点为 \(j\) 的最少代价。容易发现 \(j\) 这一维只能取到 \([\sum_{i\leq j}s_j,s_{i+1}+\sum_{i\leq j}s_j]\),所以有用的状态数是 \(O(mk)\) 的。
考虑转移。对每个人预处理出来一个背包 \(g_{i,j}\) 表示有没有一种方案选了 \(i\) 个分数公开,公开的分数总和为 \(j\)。然后据此处理出 \(mn_{i,j}\) 表示满足 \(k\geq j\) 且 \(g_{i,k}=1\) 的最小的 \(k\)。假如能处理出来这个 \(mn_{i,j}\),那么就能 \(O(m)\) 转移 \(f\) 的一个状态。
考虑如何预处理出背包。直接朴素背包是 \(O(m^3k)\) 的,可以 bitset 优化除一个 \(w\),但是对每个人做一遍肯定不行。考虑优化。注意到对于一个 \(i\) 我们只需要 \([\sum_{i\leq j}s_j,s_{i+1}+\sum_{i\leq j}s_j]\) 之中的背包状态,但是处理这些不能避免处理底下那些状态,因为要从他们转移过来。真的不行吗?我们一开始让背包全选,然后依次考虑每个物品让他不选即可。
这样背包的总复杂度降为 \(O(m^3k)\)。对于 \(mn\) 可以直接处理。于是就解决了这个题。
但是一个更为简洁的写法是,设 \(f_{i,j}\) 表示前 \(i\) 个人,公开 \(j\) 个分数的最小上端点值。这样也能做并且码量很小。
T3
\(n\times n\) 二维平面,\(n\) 次 3-side 矩形 chkmax,然后 \(m\) 次 4-side 矩形求和。3-side 矩形只有两种方向且这两种方向相对。
\(n\leq 10^6,m\leq 5\times 10^5\)。
考察每一行,发现一定是先减后增,而且一定有一个分界点使得左边的贡献全部来自于左边的矩形,右边相反。可以从上到下扫描线求出每一行的分界点。
考虑统计矩形对答案的贡献。分成左右两部分统计。竖着从左往右扫描线,搞一个线段树维护区间 \(a\cdot b\) 点积和及历史和,支持区间对 \(a\) chkmax,单点修改 \(b=0\)。
9.27
T0
给定一个长为 \(m\) 的纸带,你可以任选一个点当作起点,然后依次进行 \(n\) 次操作,操作 \(i\) 是向左或向右(由你决定)走 \(c_i-1\) 步并将你走过的格子覆盖上颜色 \(i\),起点和终点本身也算走过的。问最后有多少种结果纸带。
\(n,m\leq 150\)。
考虑倒序操作,发现当前时刻染色的一定是一段区间,区间 DP。设 \(f_{l,r,0/1}\) 表示 \([l,r]\) 这个区间被染色,且最后停留在左/右端点的染色方案数。需要对于处理辅助 DP \(g_{l,r,x,y}\) 表示使用 \([l,r]\) 区间内的操作,最远到达 \(x\),当前在 \(y\) 是否可行。可以用 bitset 优化。
T1 P4110
考虑若我们确定了一个顺序,如何计算出其期望天数。根据期望的线性性,可以把贡献拆到相邻的两天上,答案即为:
若固定选的 \(p_i\) 可重集合不变,则要最小化后面一个和式,根据排序不等式顺序和 \(\leq\) 乱序和,可以得到 \(p\) 一定不降,这样是最优的。
所以我们对原序列 \(p_i\) 排序,选的就是一个子序列。而且经过一些观察可以发现第一个和最后一个必选。这启发我们思考中间该怎么选。
假设我们固定 \(p_{i-1}=a,p_{i+1}=b\),考虑 \(p_i=x\) 怎么选。就是要最小化:
显然只需要考察 \(a+b\) 与 \(1\) 的大小关系。而 \(p\) 是递增的,所以 \(a+b\) 也是递增的,那么一定存在一个 \(a+b\) 关于 \(1\) 的大小的分界点。那么我们选的 \(p_i\) 就一定满足是选一段前缀和一段后缀。
枚举。直接双指针和前缀和优化一下就行。
T2 P12559
考虑一个询问怎么做。
容易发现,\(x\) 最终的值至少为 \(\max\{\operatorname{highbit}(a_i)\}\),设为 \(t\)。这样 \(\leq t\) 的 \(a_i\) 肯定可以一次操作消除,\(>t\) 的最多需要两次。
然而我们可以通过稍微增大 \(x\) 的值,来换取一些 \(a_i\) 的一次消除。我们把所有数按照 \(\operatorname{highbit}\) 分别拎出来,对于询问也按 \(\operatorname{highbit}\) 分组。对于每个 \(\operatorname{highbit}=t\),让所有 \(>t\) 的 \(a_i\) 拎出来和 \(x\) 全部减去 \(t\)。如果我们选择多增加一些 \(x\),那么带来额外的贡献是 \(f(x)=x-\sum_i[a_i\leq x]\)。要做的是最小化 \(f(x)\),这是一个前缀和的形式。
那这个时候就可以回滚莫队之类的鬼东西来做了,但是肯定过不了。
此时考虑一个转化:逆用 Hall 定理。
把 \(\min_x\{x-\sum_i[a_i\leq x]\}\) 变成 \(\max_x\{\sum_i[a_i\leq x]-x\}\)。
考虑 Hall 定理的形式:最大匹配 \(=|V|-\max_S\{|S|-|N(S)|\}\)。考虑构造一张二分图,让这两个式子联系起来。
建左部点为 \(1\sim n\),右部点为 \(1\sim V\)。对每个 \(i\),将左部点 \(a_i\) 连向右部点 \(1\sim a_i\) 的所有点。容易发现这样左部点失配点个数即为所求。
考虑怎么求解这种图上的最大匹配,容易发现我们按任意顺序考虑每个左部点,令其与其能匹配的最大右部点匹配即可。
考虑维护这个匹配。扫描右端点 \(r\),为了维护左端点处的答案,我们需要钦定从右到左能匹配就匹配,这样一定不劣。考虑对于匹配集合 \(S\),右部点每个值 \(x\) 维护 \(w_x=\sum_{i\in S}[a_i\leq x]-x\)。若加入 \(a_r\) 后存在 \(w_x<0\),则需要选一个最靠左的属于 \(S\) 的 \(i\),把他的匹配取消掉。那怎么找呢?考虑取消一个匹配的效果是把一个后缀 \(w_x\) 减去 \(1\),那我只需要找到最小的 \(w_x<0\) 的 \(x\),然后找一个最小的 \(i\) 满足 \(a_i\leq x\),把 \(i\) 的匹配取消掉就行。
然后考虑答案。每一个左部点能贡献到的区间是一个 2-side 矩形,直接主席树维护,查询的时候可以在线。
9.29
只选几个值得记录的题来搞。
A Q5500
每个相邻酒吧 \(i,j\) 之内的贡献是 \((i-j)(p_i+p_j)\),画到平面上表示成点 \((i,p_i)\)。不难发现除以 \(2\) 之后是一块梯形的面积,所以可以说明选的点集是上凸壳。看到这种乘积形式的东西就可以想凸性了。
D Q55
首先注意到精度要求很低,这启发我们设计一个近似算法。
二维的信息很难统计,我们考虑选一条直线投影降维变成一维,那么原本的长度变成了投影的长度。考虑让这条直线的角度取遍 \([0,\pi)\),则一条长为 \(1\) 的线段被计算的投影长度之和为:
所以算出积分答案除以 \(2\) 就行。而积分是可以近似算的。取 \(d=\epsilon^{-1}\) 即可。
E ARC158D
方程只有一个,未知数有三个,说明解很多。而且左右次数正好相差 \(1\),而且这个式子是轮换的,所以可以考虑设 \(x=ta,y=tb,z=tc\),解得一个式子。那么只要这个式子上下项都不为 \(0\) 就可以求得一组解,随机化即可。
H Q2438
考虑设 \(f_{i,j,k}\) 表示 \(i\) 个点的连通图,最小生成树的边 \(\leq j\),边权和为 \(k\) 的概率。图计数考虑反面,设一个辅助 DP \(g_{i,j,k}\) 表示 \(i\) 个点不要求联通,边 \(\leq j\),边权和为 \(k\) 的概率。
设 \(s\) 为 \(p\) 的后缀和(\(p_0\) 放到最后面)。从 \(f_{*,j-1,k}\) 转移到 \(f_{*,j,k}\) 时,一定是边权为 \(j\) 的边将一些 \(<j\) 的连通块连起来。考虑转移,图计数考虑枚举 \(1\) 所在的连通块大小,设 \(s_i\) 为 \(p_i\) 的后缀和(\(p_0\) 放到最后面),则:
正确性来源于枚举 \(1\) 所在的连通块大小来做到不重不漏。
此时发现这个东西关于 \(k\) 像一个卷积式,于是改写 \([z^k]F_{i,j}(z)=f_{i,j,k}\),\(G_{i,j}(z)\) 同理。那么可以得到式子:
对 \(z=0\sim k(n-1)\) 代入计算值,然后插值出系数就是答案。
复杂度 \(O(n^3k^2)\)。
10.2
T1
元旦激光炮。
T2
考虑一个树形 DP。设 \(f_{u,0/1/2/3}\) 表示 \(u\) 子树内的边进行操作,\(u\) 这个点不染黑/在 \((u,fa)\) 之前/时/之后 染黑的方案数。转移容易优化到常数。
边相关的树形 DP 记得考虑点和其父边到底是否被算入贡献。。。
T3
有一个无向图,每个点有点权。你每次可以选择一个连通块,将连通块内的每个点点权 \(-1\)。设 \(f\) 为将所有点点权清零的可能的最小操作次数。
有一个贪心策略来将整个图清零:首先找到点权不为 \(0\) 的编号最小点,然后将包含其的点权为正的极大连通块操作,直到清零。设这种贪心方式的操作次数为 \(g\)。
现给定一个无向图,判断是否存在一组点权,使得 \(f\neq g\)。
\(n\leq 10^5,m\leq 10^6\)。
不难发现四元环和两个三元环拼起来都是存在的。同胚的也存在。
思考这种东西的本质。有点类似于你操作一次之后会把这些东西分割成两个连通块导致他们没法互相搞。
考虑怎么构造出来一个这种东西。考虑有两个连通块 \(U,V\),若 \(U\cap V\) 不连通,那么一定可以构造出来。然后可以发现这是充要的。
所以不存在的充要条件就是任意连通块 \(U,V\),\(U\cap V\) 连通。这样可以推得如果存在一个简单环,那么他一定是个团。所以可以考虑点双。只要每个点双都是团,那么不存在。否则存在。
10.3
T1 P12572
构造懒得说。关我啥事?我过了。
T2
之前的题没搞懂,回旋镖来的太快了,。。
多了一个排列就是多一个可能的限制,照样维护即可。
T3 CF2063F2
考虑倒序操作变删点。容易发现可以建出来一棵树,删点的时候进行贡献的更新。找父亲可以用并查集维护。做完了。
T5
定义一个排列的价值为:其最长的值域连续且上升的子段长度。给定 \(n\),求所有长为 \(n\) 的排列的价值之和。
\(n\leq 3000\)。
不妨枚举这个子段的长度,设 \(L(n,k)\) 为长为 \(n\),价值为 \(k\) 的排列的个数,则答案可以简单计算。最大值恰好为某个数有点难做,不妨计算所有子段长度 \(\leq k\) 的个数,再差分。
设 \(f(n,m,k)\) 为 \(1\sim k\) 选 \(m\) 个数和为 \(n\) 的方案数,区分数之间的顺序,则有:
考虑如何计算 \(f\)。此时在前面忘了中亦有记载,反正可以 \(O(\frac{n}{k})\)。全部枚举一遍是 \(O(n\log n)\) 的复杂度。现在只需要算出 \(L(i,1)\)。
相当于一些段不能按顺序挨着。考虑容斥。钦定 \(j\) 对必须挨着,其他的不管,可以得到:
于是可以直接计算。
10.7
T2
给定一个字符串,你可以进行若干次操作,选中一个字符将其往左往右覆盖任意长度。问最终有多少种可能字符串满足最长连续相等段长 \(\leq k\)。
\(n,k\leq 5000\)。
考察一个字符串能被操作到的条件,就是其缩相等连续段之后的子序列是原串的一个子序列。那么只要求原串有多少个本质不同且相邻不相同的子序列即可。直接 DP。
T3 CF177G2
肯定得用到快速递推技巧。而又发现 Fib 数的增长是指数级的,所以可以暴力找出第一个长度大于查询串的串 \(s_i\)。然后考虑贡献。可以分为 \(s_i\) 内部,\(s_{i+1}\) 内部,\(s_i,s_{i+1}\) 之间。可以分讨之后矩阵乘法快速递推。
T4
找到 \(l-1\) 这个点往上的链第一个有不在链上的右儿子的点 \(x\),对 \(x\) 的根链执行 pushdown。\(r+1\) 同理。
注意到如果 pushdown 时有值的点数是均摊 \(O(\log n)\) 的。
于是树剖直接做就行??!!强强??!!
10.9
T2 P11126
做这道题时回忆如潮水般涌来,你充满了决心。
T3 LOJ5458
首先发现只有最后 \(5\) 列存在多次进位的情况。前面的最多一次进位。所以考虑枚举最后 \(5\) 列的值。考虑前面的进位情况,一定是一段后缀进位。枚举完了之后进位的时刻就确定了,只要判断是否存在一个位置,分讨即可。
T4 P11459
首先观察到凸性,然后可以分治合并凸包。
T5 P12992
考虑刻画连通块个数。发现其等于连接时两边度数都为 \(0\) 的边的个数。考虑对这个计数。钦定 \(k\) 条边满足上述限制,称相关的这 \(2k\) 个点为关键点,那么没被钦定的边可以分为三种:两端都是关键点、一端是关键点、都不是关键点。其中最后一类的顺序无关紧要怎么搞都行。
被钦定的边之间的顺序可以随意安排,而且因为是完全图,钦定什么样的顺序都是对称的,所以没被钦定的前两类边与被钦定的边之间的顺序可以建出 DAG,方案数为拓扑序方案数。更进一步,这个 DAG 是一棵外向树,强强??
根据树拓扑序方案数计数,可以直接写出式子:
10.11
T3
给定三个字符串,你可以在每个字符串中选出一个字串按顺序拼接起来。求拼起来是回文串的方案数。
\(T\leq 10,n\leq 1000\)。
首先你要知道字符串匹配不光可以哈希和 Z 函数,还可以 DP。。。
然后可以直接分讨做到 \(O(n^2)\)。
T4
冒泡排序终极结论:\([1,x]\) 区间内冒泡 \(k\) 轮的可重集是 \([1,x+k]\) 的可重集去掉前 \(k\) 大的结果。
此时第二问写个主席树可以直接做了。第一问,考虑二分一个 \(m\),判断 \(x\) 这个值是不是在 \([l,m]\) 内。
也即求出最小的 \(m\) 满足 \([l,m+k]\) 的第 \(k\) 大 \(>x\)。令 \(m\leftarrow m+k\),那么问题再次简化为求最小的 \(m\) 满足 \([l,m]\) 的第 \(k\) 大 \(>x\)。
也即求出最小的 \(m\) 满足 \([l,m]\) 有至少 \(k\) 个数 \(>x\)。考虑按询问的 \(x\) 倒序处理,搞一颗下标为位置的线段树,查询的时候线段树二分即可。需要注意边界。
总复杂度 \(O(n\log n)\)。
10.13
T3 UOJ961
建一个新图,若原图中 \(u\) 不能到达 \(v\),则在新图中连一条 \(u\to v\) 的边。发现这个图是竞赛图,如果 SCC 中存在一个没有弦的 \(>3\) 的环,那么可以反推得到原图中存在环,所以如果 SCC 大小 \(\geq 3\),那么一定存在一个三元环。条件变为每个 SCC 大小 \(\leq 2\)。
直接对着缩点之后的链 DP 就行了。
T4 AGC068A
因为是对称的,所以可以先选上 \(0\) 这个点。
不妨枚举一个 \(t\),钦定最大距离 \(\leq t\),这样能选的只有 \([L-i,L-1]\) 和 \([1,i]\) 这些点。这两段内部是一定不会超出限制,所以只用考虑这两段互相影响。
如果选了左边的一个点 \(p\),那么右边一段对应的长为 \(L-2i-1\) 的区间就不能选了。如果把这个点平移到左边去,那么就把问题转化为:
一个长为 \(i\) 的数轴,可以把每个点染黑或染白,一共染 \(n\) 个点,且要求一个黑点后面 \(len\) 个位置不能存在白点。直接枚举有多少个黑白切换的位置组合数计算即可。
复杂度是调和级数。
10.19
T3 P4890
遇到这种区间的题目,要意识到没有任何性质的区间相关问题是很难做的,因为一个区间会在左右端点处分别产生贡献,这就不可避免地要状压来记录之前区间的状态。于是我们肯定需要观察性质,把区间变成要么没有包含,要么没有交叉。
对于这个题,我们发现的性质是,不管门的状态是什么,一个人总能出去;只要这个人能进来,那么门可以随意选择开关。
对于一个区间 \([l,r]\),其能影响到的范围,是其 \(l\) 往右到第一个区间的端点,并上 \(r\) 往左到第一个区间的端点。这样可以把这些区间拆成若干没有包含的链,且不存在一个点被三个区间包含。对于每个链分开算再合并起来即可。
T4 P12554
首先观察到相邻同号的数可以合并,这样变成每个数正负交替。观察到若段数 \(>4\),那么可以把中间的两个数合并起来,给到旁边的一个同号段里。所以证明了最终答案分的段数不超过 \(3\) 段。而对于答案分为 \(1,2\) 段的情况,都可以平凡维护,所以这里只讨论分 \(3\) 段的情况。
很容易发现,我们可以枚举一个分割线,然后在两边各选出一个分界线作。不妨以分的三段元素和为正、负、正来考虑,左面要选前缀和的最大值 \(l\),右边要选后缀和的最小值 \(r\),此时答案为 \(\min\{l,-r\}\),因为错解不优。在分割线从左往右移动时,\(l\) 增加,\(-r\) 减小,当 \(\min\{l,r\}\) 取到最大值时,恰好是这两条折线的交点。直接线段树二分求即可。
10.25 Xi'an Regional
只记录一些非平凡题。
A
tbd
C
考虑基本情况。链和菊花显然都可行。经过一些枚举和猜测,可以知道树合法的充要条件是,不存在一个长这样的子图:
证明。充分性:考虑如果不存在这样的子图,那一定是一个毛毛虫,可以按照链的顺序操作一遍,一定能合法。必要性:不知道。总之你感受一下。
考虑求答案。容易发现这个限制满足区间包含性,可以直接双指针。维护的时候可能麻烦一点。
E
K
首先,若 \(a_i=b_i\),则不用操作肯定有解。否则一个必要条件是 \(b_i\subseteq a_i\)。把这些先判掉。
否则,这种操作一看就非常不好办,而且不能瞎操作否则很容易不合法的东西,考虑一下自由度。要想让自由度尽量大,最好的情况是存在一个排列 \(p\) 满足 \(b_i\subseteq p_i\)。可以发现这是充分的,因为可以每次消掉 \(b\) 的一个位。不妨猜测是必要的。可以直接二分图匹配,再优化一下建图,就过了。
10.27
A
平面上 \(n\) 个点,判断是否存在三条直线能经过所有点。
注意到在这 \(n\) 个点中随机选两个,这两个点在同一直线上的概率是很高的。于是直接随机化。错误概率是常数。
考虑变成确定性做法,考虑平面上任选四个点,一定存在两个点在一条直线上。于是直接做即可。
C
构造的经典思想,用给定操作构造出想要的操作。
D
首先根据极小 mex 区间理论,只有 \(O(n)\) 个区间有用。这样变成缺一个角的矩形数 max。
变成一个普通二维数点和一个平行四边形数点就可以做了。
去年 NOIP T4
发现我是不是完全没搞懂啊,再来做一下。
首先所有的 LCA 可以变成相邻两个的 LCA 的 LCA。这样 \(dep_{\operatorname{LCA}(l,r)}\) 就变成了一个区间 \(\min\) 的形式。
查询的是区间的子区间中,长度大于阈值的最小值的最大值。先给序列建笛卡尔树,这样每个点 \(l_i,i,r_i\) 能覆盖到的矩形就是 \([l_i,i):(i,r_i]\)。注意到错解不优,可以直接化成 \([l_i,r_i]:[l_i,r_i]\),效果从覆盖变成了 chkmax。
考虑修改对询问的影响。把每个修改看成一个点 \((x,y)\)。那么对于一个询问 \(l,r,k\),能影响到这个询问的修改就是一个左上矩形缺一个角的形状。
这也可以直接变成一个二维数点加上一个平行四边形数点。直接做即可。
杂题记录
CF2150C
能不能别老死磕贪心了。。。
考虑如何判定 Alice 能不能买一个集合 \(S\) 中的物品。设物品 \(i\) 再 Alice 中排第 \(a_i\) 位,Bob 中排第 \(b_i\) 位。
那么条件就是,不存在 \(i\notin S,j\in S\),满足 \(a_i<a_j\) 且 \(b_j<b_i\)。
换句话说,对于所有 \(i,j\) 满足 \(a_i<a_j,b_j<b_i\),如果 \(i\in S\),那么必定有 \(j\in S\)。放到二维平面上就是如果选了一个点,那他右下的所有点都必须选。然后可以发现选的轮廓是左下-右上阶梯形的。
设 \(f_{i,j}\) 表示从下往上第 \(i\) 行,分界线在 \(j\) 的最大价值。看似转移很多,其实只要规定这个分界线的拐角必须是卡着点的,即可线段树优化 DP。\(O(n\log n)\)。
另一个思考方式是,把这个两个排列置换成 \(a_i=i\),以此来简化形式。容易发现这样可以直接把二维平面踩在地上。
CF2147F
这题怎么也是两个排列,那还是先置换,变成 \(p_i=i\) 的情况。
可以先图论建模,连出边来,然后缩 SCC,设 SCC 大小为 \(s_i\),答案就是 \(n+\binom{n}{2}+\sum_i \binom{s_i}{2}\)。于是现在要维护每个 SCC 的大小。
考虑 \(p\) 上的连边,是一条链,那么 \(q\) 上只有往回的连边是有用的。考察每个 SCC 的大小,相当于考察分界点的位置。一个点是分界点,当且仅当其不被一个往回的连边覆盖。
于是可以线段树维护最靠左、最靠右的最小值位置,以及一些贡献。修改的时候是一些区间加加减减,反正可以 pushup。复杂度 \(O(q\log n)\)。
我真的理解了吗。。?我没有理解。其实这个题跟排列这一性质密切相关。置换成 \(p_i=i\) 之后,可以处理出来一个排列 \(o_i\) 表示若 \(o_i>o_j\),则可以从 \(i\) 走到 \(j\)。进而可以发现如果 \(x\) 是一个分界点,那么 \([1,x]\) 的 \(o_i\) 的值域应当也是 \([1,x]\),否则总可以跨过点 \(x\)。
于是只需要判断一个点 \(x\) 左边的 \(o_i\) 的值域是不是 \([1,x]\)。可以线段树维护左边有多少个 \(o_i>x\)。
CF2055E
首先可以发现,一定是按照某种顺序挨个清空每个堆。所以答案只与这个顺序有关。
考虑确定了顺序,我们该如何求出最小的花费。首先每个草至少移动一次,然后在挨个清空的过程中,应该尽量放满那些已经被清空的堆,如果放不进去,那么应该放到最后一个堆。则放到最后一个堆的数量为:
用折线图刻画一下,原因显然。
要最小化上式的值,考虑邻项交换。若 \(i\) 项在 \(j\) 项前面更优,那就是:
这不是我们加工生产调度吗。
P1248
首先邻项交换得到跟上面相同的形式,但是直接按照这个 sort 发现过不了。
原因是这个比较函数不满足严格弱序的性质。严格弱序就是满足反自反、反对称、传递、不可比传递。如果你真的验证一下可以发现这个比较函数不满足不可比传递,也就是说当 \(\min\{a_i,b_j\}=\min\{a_j,b_i\}\) 的时候,还需要进一步比较。可以简单得出此时要按 \(a\) 来排序。于是可以通过。
CF2056F2
看到异或计数,肯定考虑抵消。容易发现计数的主体是序列,而我们只关心其组成成分,所以一种组成成分对应的序列有
种。而且这些方案的贡献相同。不难想到只有其 \(\bmod 2=1\) 才有用。而有:
右式要想是奇数,那么必须每项都是奇数。使用 Lucas 定理,可以得出 \(c\) 序列其实是 \(n\) 的一个二进制分解。考察 \(n\) 的最高位,发现其一定 \(>\frac{n}{2}\)。所以包含这个的 \(c_i\) 一定是中位数,也是最大的 \(c_i\)。
考虑计数。答案是:
关于斯特林数的奇偶性,可以打表观察,这里给出式子:
可以枚举 \(i\),然后计算 \(i-1\) 的超集的异或和。
福建省集 D6T1
给定 \(n,m\)。从 \(1\sim m\) 中随机选出 \(n\) 个两两不同的数 \(a_{1\sim n}\),将其升序排列。对于 \(1\leq i\leq n\),令 \(b_i=a_i−a_{i−1}\),特别地,\(a_0=0\)。将 \(b\) 升序排序。令 \(c_i=\sum_{j=1}^i b_j\)。对 \(i=1\sim n\),求 \(c_i\) 的期望值。
\(n,m\leq 10^6\)。
首先因为期望的线性性,可以直接转为对每个 \(i\) 求 \(b_i\) 的期望。不妨对每个 \(p\) 枚举一个值 \(q\),计算 \(b_p=q\) 的概率。可以容斥成计算排序之前 \(\sum_{i}[b_i\leq q]\geq p\) 的概率,表示 \(b_p\geq q\) 的概率,然后差分回来即可。
考虑怎么算。可以钦定 \(k\) 个 \(b_i\leq q\),然后反演出恰好 \(k\) 个 \(b_i\leq q\) 的概率。然后可以搞。
更进一步,我们发现涉及到的所有操作都是线性变换,且只与下标有关,所以可以把所有的值塞到一块整体二项式反演。\(O(m\log m)\)。
P4707
不妨令 \(k\) 为 \(n-k+1\),要求即为 \(E(\operatorname{kthmax}(S))\),min-max 容斥转化成求:
其中 \(E(\min(T))=\frac{m}{\sum_{i\in T}p_i}\)。
于是可以设计一个 naive 的 DP,设 \(f_{i,j,s}\) 表示前 \(i\) 个选了 \(j\) 个 \(p_i\) 和为 \(s\) 的方案数。\(O(n^2m)\) 过不去。
考虑把系数也放进状态里,有组合数的递推式。于是可以设状态 \(f_{i,j,s}\) 为前 \(i\) 个数,和为 \(s\),\((-1)^{|T|-j}\binom{|T|-1}{j-1}\) 的和,可以简单转移。复杂度 \(O(nkm)\),可以通过。
CF2154F2
考虑合法的充要条件,就是其逆排列最多存在一个 \(p_i>p_{i+1}\)。可以枚举分界线位置,然后答案是一些组合数乘积。直接做可以 \(O(n^2)\)。
注意分界线向右移动一格,有一些组合数的下指标会减小 \(1\)。而上指标之和是 \(O(n)\) 的,所以每次暴力修改即可做到 \(O(n)\)。
CF1442E
考虑没有灰点的情况,先把同色点缩起来,容易发现答案是关于直径的,考虑每次剥掉同色的叶子即可。
现在要给每个灰点分配一个颜色,让其缩点之后直径长度最小。直接树形 DP,让子树里最长的那条链延伸出来即可。
ARC155D
考虑当前的 \(g\)。若 \(g\nmid a_i\),则 \(a_i\) 一定没被选,剩下的可能被选。进一步可以发现我们只关注剩下的数的奇偶性。于是可以直接莫反优化 DP。
P10805
考虑点分治。然后把路径拆分成 \(u\to r\) 和 \(r\to v\)。这里我们不钦定 \(u,v\) 不在同一子树中,最后容斥减去即可。
容易发现一辆车加油之后就不关心他的起点了,于是可以 DP 和倍增处理出到 \(r\) 的车的剩余油量集合和 \(u\to r\) 的加油贡献。
对于 \(r\to v\),我们也只关心其第一次被加油,后面的可以相似处理。枚举点,在这个点第一次被加油的车的数量就是一个区间和。直接做即可。
Q12317
唐点解析:\(\max_{i<j}f_i+g_j\) 可以直接用线段树带修维护。
P13046
一年前被击败,现在来反过来击败。
首先有一个 naive 的 DP,可以用桶优化转移。但是当 \(\gcd(10,D)\neq 1\) 时因为没有逆元会出错。
所以把 \(2,5\) 这两个质因子拎出来考虑。现在变成形如 \(\sum_i 2^{i-l}5^{i-l}a_i\equiv 0\pmod {2^p5^qd_0}\)。
那么只要 \(i-l>\max\{p,q\}\),就可以把这两个质因子扣掉,沿用桶的优化。而对于 \(i-l\leq \max\{p,q\}\),这部分的长度是 \(O(\log d)\) 的,直接转移即可。
P13842
首先注意到 \(a_i>b_i\) 的 \(i\) 最多选 \(1\) 个。所以可以先把 \(a_i<b_i\) 的答案算出来,看能不能无损加入一个。如果此时直接做是一个什么在线矩形加全局 \(\max\) 的东西。
注意到若两个 \(a_i>b_i\) 的区间互相包含则大的一定没用,于是现在只有相交关系,可以转化成二维数点计算前面的贡献之后线段树维护。
继续注意。若一个 \(a_i>b_i\) 包含 \(a_i<b_i\) 的区间,则大的那个是没用的。则可以简单转化为两个一维数点,线段树维护即可。
Q13235
首先考虑反面,计算 \(1,2\) 可达点集不交的方案数。
考虑计算 \(f_S\) 表示 \(1\) 恰好可达 \(S\) 内点的方案数。这样把 \(2\) 的也计算出来之后可以 \(O(3^n)\) 合并答案。
怎么算 \(f_S\)?考虑一个容斥。\(S\) 集合内乱连是 \(2^{E_S}\) 种方案,枚举 \(1\) 可达的一个连通块,然后钦定外面的不能到达,即可转移。
代码源 D9T2
给定 \(n\) 个三元组 \((a_i,b_i,c_i)\)。求:
\(n,V\leq 10^7\)。
何意味??!!??
考虑两个怎么做:
容易桶维护。
三个呢??!!??
按照原则来说,沿用之前的方法肯定是不行了。所以我们需要另辟蹊径。
注意:
就变成了两个的形式,容易线性维护。
回顾一下这道题,一步是凭空变出来一个 \(\min\),另一步是对 \(\max\) 使用 min-max 容斥。而且因为 \(3\) 是奇数,可以恰好消掉!

浙公网安备 33010602011771号