Day Inf【3、12~24】

Day3

列队:注意到学生的相对顺序不会变,然后你可以区间查询然后线段树二分加一点点简单的贡献计算解决。

可持久化串串:对 Trie 倍增,维护跳 nxt 的过程,如果 nxt 走的不超过一半,则这个串的后缀必然有循环节,跳过这些循环节找到最前面不规则那一段即可。


Day12

新知识:Dsu on tree。

在计算树上路径问题中,亦可使用点分治。

思想就是每次只保留重儿子的信息且回溯给父亲,其它点的信息暴力计算然后最后删除。如果是路径问题,记得加入一个子树过后要统一计算一次答案。

复杂度是线对,证明考虑一个点被暴力加的次数为对数次即可(假设加入删除复杂度均摊 \(O(1)\)

void Dfs(int x, int y, bool f) { 
	for(int to : G[x]) {
		if(to == y or to == son[x]) continue ;
		Dfs(to, x, 0);
	} 
	if(son[x]) Dfs(son[x], x, 1); 
	for(int to : G[x]) {
		if(to == y or to == son[x]) continue ;
		for(int i = L[to];i <= R[to]; ++i) add(ifn[i]);
	}
	add(x);
	ans[x] = get();
	if(!f) {
		for(int i = L[x];i <= R[x]; ++i) del(ifn[i]); 
		maxn = sum = 0;
	}
}

至于习题,注意 >= k 的信息数组也是可以计算的。

Digit Tree:显然你考虑 LCA,然后路径分为上升段和下降段,我们在 dsu 的时候钦定了 LCA,枚举 x,那么用 map 记录之前加入的 y 的信息即可。


Day13

Deblo:拆位树上路径算贡献,简单题。

Ridiculous Netizens:树上依赖背包,考虑点分治计算所有点作为中心的答案,同时保证复杂度线对。至于背包部分,考虑根号分治,当 \(V\ge \sqrt m\) 的时候改成记录 \(m/V\) 即可,保证了状态数是 \(\sqrt m\) 级别。

感染:点分治优化前缀优化建图。容易发现一个点能连出去的点是树上是联通的,但是 dfn 不一定连续,但是如果点分治过后就是在一条路径上了。就是看新图中有多少点 in = 0。

考虑每个点拉出子树内所有点,按照 dis 排序然后连边,不用考虑同一条链上互相连边算重的情况,这并不影响。容易发现每个点练出去的都是一段前缀。直接前缀优化建图。

很好证最终边数在线对级别。

幻想乡战略游戏:点分树优化找重心的过程。选点分树根开始,向所有儿子走,判断移动是否优(唯一性)。这个判断就点分树上跳 fa,容斥掉 fa 在来源点的贡献。


Day14

Empty Rectangles:分治到中线 \(mid\)(行),枚举列 \(l,r\)。发现每个 \(k\) 都有一个行决策点。所以维护指针移动预处理,然后合并上下信息即可,复杂度 \(O(m^2k\log n)\)

拦截导弹:三维偏序的 dp,用 cdq 套 bit 优化 dp。由于计算方案数,所以倒着再 dp 一次算出 i 作为起点的最大值方案数,和终点合并即可。


Day??? 初三杂题巩固

通配符匹配:显然分成多个分配符的段进行 dp,转移有 3 种,条件都是哈希判断,有一个 ? 的转移要前缀和优化。

稻草人:晚测,按照 y 的顺序加入点,就是线段树维护丹钓战的板子,虽然我不是很熟。

赛道修建:显然一个子树只能上传 1 个有效路径,并且每次我们需要子树贪心地合并。贪心考虑从小的开始匹配。


Day17

矩阵乘法:整体二分,矩阵就是 01 的。

Sequence 数字序列:首先所有数减去 \(i\) 变成不严格旦增。二分的时候计算 2 个边界点的答案。

接水果:套了个二维偏序,注意第一维要强制小于第二维。对于时间轴我们要预先排序。

网络:判断一个点是否被完全覆盖。


Day18

炸弹:显然 ds 优化建图。缩点之后跑一个反向图的 dp,记录 L,R 即可。

PUS:一眼,限制只会划分成 \(O(k)\) 个段,考虑这 \(k\) 个点连向这些段,建一个虚点连向这些点,然后这个虚点用 ds 建图连向这些段即可,最后还是简单 dp 一下。

Tax:先考虑所有边都是出边,那么我们排序过后依次连边。又考虑入边,直接连向反边,边权为 0。想到这里自然地把边给变成点。建图很有网络流的味道。

Duff in Mafia:https://www.becoder.com.cn/article/15997


Day20

选举:显然所有 B 要先选,所以按照 b 排序,答案就是一段后缀全部选 a,前缀选一些 b,这玩意可以枚举选 b 的个数,然后 dp。

有趣的家庭菜园 2:前后互不影响,所以可以合并前后缀答案,线段树优化 dp。

有趣的家庭菜园 3:\(f(i,j,k,0/1/2)\) 表示前 \(i\) 个合法,当前是什么元素,我们考虑此时第 \(j\) 个 op 元素在当前状态下在什么位置,以及 \(j\) 这个地方考虑一下另外两个 op 的移位带来的影响。(显然相同元素相对顺序不会变)

配对游戏:对每一位算贡献,本质是长为 \(n-i\) 的随机 \(1/-1\) 序列前缀最小值不小于 0 的概率,或者可以直接按照题意 dp 转移。

Phoenix and Computers:1. 连续段 dp,很好写。

2.考虑在序列后面加入一段全部是手动开启的电脑段(一),然后中间间隔一个电脑来自动开启。转移系数就是相对顺序的交。然后还要算一下(一)的方案数。(枚举第一个操作位置,两边操作相对顺序固定,合并代价是组合数。这些组合数相加是一个 2 的幂)

Od deski do deski:\(dp(i, j, 0/1)\) 表示 \(len = i\),前面 \([1, x]\) 的合法位置有 \(j\) 个,当前是否是合法的,转移很简单。一般这种题都要升维。0/1 也是常规。


Day21

Tree:首先要选联通的。然后结论:边权和 - 直径。所以这个树背包算一下就可以了。

贪玩蓝月:删除操作很麻烦因为两端插入没办法维护前缀,考虑双栈维护前缀。现在考虑一个栈空了怎么办。一种方法是把另一个栈一半搬过来然后重新预处理。定义势能函数:\(F = |siz1 - siz2|\),一次插入/删除使势能变 \(1\),消耗 \(O(p)\)。一次重构消耗 \(O(Fp)\),让势能清 0,也就是变化 \(F\)。所以这样分析下来消耗 1 势能的代价是 \(O(p)\)

合并的时候枚举一边 V,另一边用 st 表求区间 dp 最大值。

Polarization:最小值考虑每一层边方向一样,下一层方向取反。这样就是 \(n-1\)。考虑最大值,结论是选择重心,子树一些点全部向上,其余向下。(感性证明,如果你多个点这样的话贡献是不如一个点的)

那么现在就是背包合并所有子树的 siz。这是经典问题,用 bitset 优化可以 \(O(n^2/w)\)。但是这个题比较特殊,\(siz\) 和是 \(O(n)\) 级别,考虑根号分治。如果个数太多了,可以通过把一个 \(V\) 较小的物品的 \(cnt\) 二进制拆分给那些大的 \(2^kV\) 的数,复杂度 \(O(肯定能过)\)

苹果树:明显选择一个叶子结点。然后做树上依赖背包。(可以先做一次 01 背包,再做多重背包,解决强制的问题)对一条链做前后缀的依赖,合并前后缀背包。(不妨后缀不选链,前缀选链)

弗雷兹的玩具商店 / Toyshop:\(m<60\) 就很奇怪啊。体积只有 60 种,明显只保留每个体积的 max 就行了。这个东西用线段树维护,每个节点存长度为 \(m\) 的数组。每个操作形如区间移动,区间加。询问就把 \(m\) 个物品取出来暴力 dp 即可。


Day22

字符串折叠:区间 dp,特殊处理一个区间全部循环节的贡献。

Jumping sequence:很明显还是要转坐标轴使得 \(x,y\) 独立吧。然后就是一些讨套路处理。

梦幻岛宝珠:\(b\le 10\),首先我们可以给每个 \(b\) 做背包,最后类似倍增并查集一样合并即可。如果记录剩下多少个那么上界就是 10n 级别。

波浪:连续段 dp,需要钦定左右是否碰到了边界,输出是勾石。

Elevators of Tamem:把 \(n\) 变成 \(q\),然后注意这一位一定有一维是 now,然后枚举哪一位是 lst 转移即可做到单次 \(O(q^2)\)

New Year Shopping:线段树分治板题。删除操作就存背包数组即可。


Day23

括号序列:肯定要记录全是 * 的段,合法段,SA,AS 段,转移简单。但是合并会算重,所以强制合并合法串有一个是 (A) 类型的。

甲虫:发现可能走到后面露水负数了,所以我们还要钦定最终走到了 \(k\) 个露水,贡献就可以算了。

方块消除:显然要加维,表示后面加上和 \(col_r\) 颜色一样的数量。转移条件是 \(col_{mid}=col_r\)

Coins Exhibition:可以容斥,但是我们可以对每段 dp,0/1/2 表示全 0/1,01 都有。转移 0/1 的时候就找到上一个 0/1 然后算一个后缀和即可。

Encoding Subsets:确定字符串 dp 很好做,3 次方即可,考虑子集。发现给循环节个字符串取交就是我们要求的东西(单个没有合并的),但是这玩意没法定义状态。不妨把字符串当做状态。然后简单。复杂度不是多项式刻画,能过。


Day24

Paint:显然可以合并成 \(r\) 的颜色,然后简单 dp。保证了 \(k\) 最多 20 个。

Candles:和昨天的题有所区别,可能中间是负数,那么我们状态加入【外面还剩多少个计算即可】。

字符合并:1:区间合并,按照不算重的套路,钦定后面只接入 0/1;2:整个区间操作,肯定最后只剩下一个 1,经典结论:\(n-1\equiv 0 \pmod {k-1}\),要加入辅助数组。整个串都合并成 0/1。1 的复杂度太高需要优化,发现后面能接入 0/1 的点都必须通过 2 合并,于是每次就移动 \(k-1\),能过。

Split and Insert:正难则反想到了,最终相当于要升序,操作变成将一段子序列移到后面去,这个东西刻画到值域上就好做了。显然我每次要把区间里面最大的数放到后面去,所以 \(dp_{t,l,r}=dp_{t+1,l,x}+dp_{t+1,x+1,r}+(r-x)\times c_t\),类似 01 背包,我们从大到小枚举 \(len\),做 \(k\) 次 dp 即可,这杨甚至可以省掉第一维。注意预处理最大值域上升段。

Chords:经典容斥。枚举断点,钦定前面一段合法/联通,后面全部内部连边。现在看起来确实显然 (9.17)。

posted @ 2024-09-06 17:09  LCat90  阅读(6)  评论(0编辑  收藏  举报