[杂题合集] 25 岁小伙突然没了心跳,他的习惯很多年轻人都有!

戳我掌握流量密码!

砍竹子

题目描述

(n) 棵高度为 (d_i) 的竹子。一次操作 ([l,r]) 可以使 ([l,r]) 之间的竹子高度减一,你不能操作高度为零的竹子。首先,你需要 最小化 将所有竹子砍没的操作次数。另外,对于操作 ([l,r]),它的权值为 ((r-l+1)^2),你还需要计算,在最小化操作次数时,可以构造的最大与最小的权值和。

权值和对 (10^9+7) 取模。

(nle 3cdot 10^5,0le d_ile 10^9)

解法

首先,这种区间权值加/减问题一般先差分看一下:令 (c_i=d_i-d_{i-1}(1le ile n+1))。这样一次操作就可以转化为选择 (i,j(1le i<jle n+1)),令 (c_ileftarrow c_i-1,c_jleftarrow c_j+1)。转化之后,就可以发现最小操作次数就是 (sum_{i=1}^{n+1} max{c_i,0})

考虑证明。首先由于 (d_0=d_{n+1}=0)(sum_{i=1}^{n+1}c_i=0)。而且由于 (forall iin[1,n],d_ige 0),我们可以保证 (forall iin[1,n+1],sum_{j=1}^ic_jge 0),这也就意味着每个小于零的 (c) 都可以和前面某些 (c) 进行匹配,变成零。所以 (sum_{i=1}^{n+1} max{c_i,0}) 就是总的匹配对数,而且,(sum_{i=1}^{n+1} max{-c_i,0}) 也是答案。

接下来考虑如何最大/最小化权值和。

先给出构造方法:在遍历到 (c_i>0) 时,将其塞进一个队列。对于最大化,就是将 (c_i<0) 的数字尽量与队尾匹配;反之,尽量与队头匹配。

证明可以用调整法。假设 (i<i'<j<j'),现在 ((i,j),(i',j')) 各进行 一次 匹配,我们需要证明这比 ((i,j'),(i',j)) 各进行 一次 匹配更小。首先可以发现这两种方案第二项的和减第一项的和相等,那么实际上就是研究函数 (y=x^2+(a-x)^2=2x^2-2ax+a^2),画出图像可知,当 (x,a-x) 接近时总和更小。所以结论得证。

复杂度 (mathcal{O}(n))

( ext{BZOJ - 4238 })电压

一直觉得图论是基础板块最难的...

首先得出合法的边满足 —— 在 所有 奇环上且不在任一偶环上。

生成一棵 ( m dfs) 树,此时非树边只可能是返祖边,可以证明,当图中 "奇环" 个数不为 (1) 时(需要注意的是,这里的 "奇环" 指的是 一条 非树边与许多树边形成的环),非树边一定不可能合法。可以分类讨论(显然,这条非树边必须在 "奇环" 上才有讨论的价值):

  • 若存在 "奇环" 未对此边形成包含关系(包含:在同一条树链上且不相交)。此时一定不合法。
  • 若所有 "奇环" 均对此边形成包含关系。此时包含这条边的 "奇环" 数量一定 (>1),而任选一个组成边中没有这条边的 "奇环" 就能和组成边中有这条边的 "奇环" 就能构成一个偶环!

所以结论得证,我们现在只需要关心树边。这个就比较好判断了:当遍历到返祖边 ((u,v)) 时,查询 (u,v) 的深度差就可以知道 (u,v) 之间的一系列树边在什么类型的环上,做一个树上差分即可。

需要注意的是,上面的结论没有包含只有一个 "奇环" 的情况:事实上,这也只包含一条非树边!所以特判即可。另外就是此题有重边,而且重边会干扰判断,所以要用前向星。

( ext{LOJ - 6062 Pair})

这是怎么想到是图论的啊。

({b}) 的顺序对答案无影响,我们将其升序排序。那么此时 (a_i) 就可以和 ({b}) 的一个后缀全部配对。

我们发现题目条件很类似于二分图中的 "完备匹配" 的概念,就转化为 ({b})({a}) 中一段长为 (m) 的连续序列是否存在完备匹配。利用 ( m Hall) 定理,完备匹配存在当且仅当对于 ({b}) 的任一子集 (S) 都有 (|S|le |N(S)|)

枚举子集是不现实的,但我们发现 (b_i) 更大时,对应的匹配只会更多,所以实际上只需要检查 ({b}) 的每个前缀是否满足条件即可。用线段树即可简单维护。

尽梨了

题目描述

丰之崎学园附近共有 (n) 个商店,在时刻 (0) 时,英梨梨从学园出发开始购物。

从学园走到任意一个商店,或从一个商店走到另一个商店需要 (1) 单位时间。如果英梨梨在时刻 (t) 到达了商店 (i),她需要先花费 (a_i ×t + b_i) 的时间排队,然后才能购买这家商店的物品。

英梨梨想知道,在时刻 (T + 0.5) 之前她最多能在多少个不同商店买到物品呢?

这里假定只会在走路和排队上消耗时间,购买物品不消耗时间。

(1le nle 2cdot 10^5,0le a_i,b_i,Tle 10^9)

解法

首先可以贪心将商店排序,有一个朴素 (mathcal{O}(n^2))(mathtt{dp}) 做法。

但实际上,当 (a_i>0) 时,每次进入商店之后,时间至少翻倍,这种情况 (mathtt{dp}) 就是 (mathcal{O}(nlog T)) 的。发现 (a_i=0) 的情况在排序序列末端,这种情况枚举 (mathtt{dp}) 值的第二维,贪心即可。

(sf{[CERC2016] Bipartite Blanket})

先给出结论:

在二分图 (G) 中,若左部点集 (S'subseteq S),右部点集 (T'subseteq T) 都能 各自 被一个匹配覆盖,那么 (S'cup T') 也能被一个匹配覆盖。

考虑证明。首先,不妨在图上只保留 (S',T') 和与其各自匹配相连的点,还有匹配边。不难发现这张图每个点的度数 (le 2),也就意味着这张图由多条链和环组成。我们只需分类讨论:

  • 环。由于是匹配,所以一定是偶环。其次,由于度数为 (2) 的点一定属于 (S')(T'),所以环上相邻点可以一一匹配。
  • 链。只有链的两端不属于 (S')(T'),长度为偶就直接匹配,为奇就让链端旁的点和链端匹配。

于是我们只需要分左右两部判定 ( m Hall) 定理即可。

最短路径

题目描述

给定一棵 (n) 个结点的无根树,树上标记有 (m) 个互不相同的关键点,小 ( ext A) 会在这 (m) 个点中等概率随机地选择 (k) 个不同的点放上小饼干。

你想知道,经过有小饼干的 (k) 个点的最短路径长度的期望是多少。注意,你可以任意选取起点和终点,路径也可以经过重复的点或重复的边。

答案对 (998244353) 取模。

(2le kle mle nle 2000,mle 300)

解法

草,这题直接卡在第一步了... 首先考虑固定 (k) 个点的最短路径长度,其实就是所有被包含的边 ( imes 2) 减去直径。

将这两坨绑在一起不好算,所以拆开算:

对于前一坨。枚举所有边,每条边将树分成两坨,设第一坨小饼干数量为 (p),那么这条边被包含的方案数是 (inom{m}{k}-inom{p}{k}-inom{m-p}{k})。就是去掉小饼干全在某一坨的情况。

对于后一坨。首先直径的两个端点一定有小饼干,那么可以 (mathcal O(m^2)) 地枚举直径。考虑到可能有算重的情况,我们指定偏序关系:长度相等时,选择双元组 ((u,v)) 更小的(保证 (u<v))。

不过复杂度无法承受,事实上,枚举 ((u,v)) 时我们只用判断以下条件:

  • ( ext{dis}(u,x)> ext{dis}(u,v) ext{ or } ext{dis}(v,x)> ext{dis}(u,v))
  • ( ext{dis}(u,x)= ext{dis}(u,v) ext{ and }x<v)
  • ( ext{dis}(v,x)= ext{dis}(u,v) ext{ and }x<u)

(x) 不合法 当且仅当 满足以上任意条件。现在需要证明,这个条件判定合法的 (x,y) 不会变成优于 (u,v) 的直径。这其实比较简单:首先可以得知 ( ext{dis}(x,y)) 至多等于 ( ext{dis}(u,v)),而且此时一定分别满足条件 (2,3),根据定义的偏序关系,不可能优于 ((u,v))

这就变成 (mathcal O(m^3)) 的了。

奶油蛋糕塔

题目描述

今天的 ( m Kiana) 是一名糕点师,她的任务是制作出最美味的奶油蛋糕塔。

( m Kiana) 一共有 (n) 块蛋糕用于制作蛋糕塔,其中第 (i) 块蛋糕的美味度为 (d_i)。每块蛋糕的顶面和底面都各涂有一种奶油,奶油总共有四种不同的类型,分别用字母 XYZW 来表示。由于不同种类的奶油混在一起会变得难以下咽,因此 ( m Kiana) 规定,一块蛋糕能够放在另一块蛋糕上面,当且仅当前者底面的奶油和后者顶面的奶油是同一种类的。

为了制作尽可能美味的蛋糕,( m Kiana) 允许对每块蛋糕进行翻转,制作好的蛋糕塔的美味度为使用的蛋糕的美味度之和。现在 ( m Kiana) 想知道,自己能做出的美味度最大的奶油蛋糕塔美味度是多少。由于 ( m Kiana) 自己不会算,所以希望你能够帮助她。

(1le nle 5cdot 10^5)

解法

将颜色转化成点,蛋糕转化成边,这就变成了一个图论问题:你会发现,当走到一个点时,就可以选择自环;且两条重边可以等效为自环处理。

于是只用判定原图是否存在欧拉路,如果有就可以选择所有的蛋糕,反之我们只用放弃一条边:由于原图只有四个点,那么不满足条件就只有四个点度数均为奇的情况,此时选一条边删去就是合法的情况了。

三/四元环计数

三元环计数

将度数大的向度数小的连边,对于每个点 (x),枚举出边到 (y),再从 (y) 枚举出边到 (z)。看似挺暴力,其实这是 (mathcal O(msqrt m)) 的。

考虑证明,首先 (x ightarrow y) 可以看作枚举所有的边,我们以 (y) 的出度分两种情况讨论:

  • 出度 (le sqrt m)。就是 (mathcal O(msqrt m)) 的。
  • 出度 (> sqrt m)。此时 (x) 的度至少有 (sqrt m),所以个数不超过 (sqrt m)。那么一个 (y) 的贡献就是 (mathcal O(sqrt mcdot ext{out}_y)),总共是 (mathcal O(msqrt m)) 的。

四元环计数

不会证明复杂度,但也是 (mathcal O(msqrt m)) 的。具体差不多是将两块拼在一起。

inline bool cmp(const int& _this,const int& _that) 
	{return d[_this]<d[_that]||(d[_this]==d[_that]&&_this<_that);}
#define con const int&
inline void main() {
	n=g(),m=g(); for(R i=1,u,v;i<=m;++i) 
		u=g(),v=g(),e[u].push_back(v),e[v].push_back(u);
	for(R i=1;i<=n;++i) d[id[i]=i]=e[i].size();
	sort(id+1,id+n+1,cmp);
	for(R i=1;i<=n;++i) rk[id[i]]=i;
	for(R u=1;u<=n;++u) for(con v:e[u]) 
		if(rk[v]>rk[u]) f[u].push_back(v);
	for(R u=1;u<=n;++u) {
		for(con v:e[u]) for(con w:f[v]) if(rk[w]>rk[u]) ans+=c[w],++c[w]; //交换e与f的枚举顺序也是对的。
		for(con v:e[u]) for(con w:f[v]) if(rk[w]>rk[u]) c[w]=0; //清空桶。
	} printf("%lld
",ans);
} 

( ext{CF730E Award Ceremony})

加强版:输出队伍顺序。

首先想到将总贡献拆分成两两队伍的贡献,我们发现只有三种情况:

  • 改变零次。这个不予考虑。
  • 改变一次。此时无论哪个在前面,贡献都为 (1)
  • 改变两次。枚举可知,这确定了唯一的偏序关系,而且两支队伍的变化方向一定是 同向 的!这也就意味着按 "先 $ ightarrow $ 后" 连边,此时一定不会出现环,也就是说所有偏序关系都可以选择。输出队伍顺序就是做一遍拓扑排序。

( ext{CF883B Berland Army})

首先可以用两次拓扑求出每个点取值区间 ([l_i,r_i])

可以想到枚举权值然后分配,就拿从大到小来说吧:假设枚举到 (i),那么 ([i+1,k]) 的数字都已经分配完毕,所以此时还没有被分配到的下界为 (i) 的点必须分配为 (i)

如果没有这样的点呢?此时下界越小的点能覆盖的越远,所以选择下界最大的点覆盖。

买零食

题目描述

你有 (x) 元人民币,你想用这些钱购买数量最多的薯片,为此你甚至能接受乐事新出的芥末味。

具体地,芥末味和番茄味的薯片分别用一对 ((x_i,y_i)) 来描述 —— 当购买第 (j) 包同类薯片时,花费为 (y_icdot (j-1)+x_i) 元。

(q) 个询问,每次询问给出 (x_1,y_1,x_2,y_2,x)。请输出能购买的最多薯片数。

(q) 之外的数字在 (10^{18}) 以内。

解法

首先可以想到会让购买两种薯片的单次最高价格尽量接近,于是我们不妨二分这个最高价格,再倒推出购买了多少包薯片。

需要注意的是我们不总能二分出最优解,比如这种情况:

1 1 1 1 11

最优解是分别买 (2,3) 包,但你会发现上文的二分只会考虑分别买 (2,2) 包,(3,3) 包的情况,为什么?

将薯片价格放在数轴上,你会发现一个点可能存在多种薯片,这很类似于主席树上二分第 (k) 大。但幸运的是,根据题目规则一个点只会存在两种薯片,所以我们只需要在倒推出购买多少包薯片后,再各自往后推一包薯片就可以解决这个问题。

妄想集合

考虑一个最大的集合无法组成三角形 —— 这就是斐波那契数列。

而在 (10^9) 的范围内数列只有 (44) 项,由于题设中每个集合初始至少有一个数,所以只要询问的长度大于 (44) 就可以直接输出 YES;若否,直接暴力遍历即可。

对于修改,可以使用并查集加速遍历:维护上一个集合大小没有超过 (44) 的位置。

时间复杂度 (mathcal O(44n))

( ext{CF734E Anton and Tree})

为了方便观察,我们首先将同色连通块都缩成一个点,生成的新树显然相邻节点是异色的。

不妨先考虑一条长为 (d) 的链的情况:此时从最中间的点开始扩展(如果长度为偶数就任选中间一点),不断翻转颜色,就能得到最优解 ((d+1)/2)

一棵树其实也是类似的,选择直径最中间的点开始扩展,你会发现延展出的 "枝桠" 都已经被覆盖了(其实可以看作是多条链,有些重合),所以可以在 ((d+1)/2) 次操作内完成任务。而且 ((d+1)/2) 次操作也是操作完树的直径至少花费的次数,所以不会有更优解。

具体实现时压根不用缩点,只需要将异色边赋值为 (1) 再求直径即可。

( ext{CF1383A String Transformation 1})

首先将 (a_i) 改成 (b_i) 的操作变为一条从 (a_i)(b_i) 的有向边,可以发现这一定是一个 ( ext{dag})

事实上,如果存在 (langle x,y angle)(langle y,z angle),我们就不需要保留 (langle x,z angle)。于是只用保留每个弱连通块的生成树即可。

( ext{CF1483C Skyline Photo})

首先可以想出一个 (mathcal O(n^2))(mathtt{dp}),可以发现,(w(j,i)) 就是以 (i) 为结尾,开头在 ([j,i]) 中的后缀最小值,这不由得使人想到 单调栈。话说以前用单调栈求一个数的极长区间时都没有仔细想过它和后缀最小值的联系...

维护一个单增的单调栈,那么元素 ( ext{stk}_i) 的统治区间就是 (( ext{stk}_{i-1}, ext{stk}_i]),也就是说,用区间 ([ ext{stk}_{i-1}, ext{stk}_i))(mathtt{dp}) 值进行转移时,对应的 (w) 都是 (b_{ ext{stk}_i})。于是可以维护一个线段树,当元素入栈时在对应的转移区间加上 (b),弹出时减去即可。

事实上,我们也不需要线段树。假设用 (pre_i) 维护了区间 ([ ext{stk}_{i-1}, ext{stk}_i))(mathtt{dp}) 值的 (max),那么加入元素 (x) 时,弹栈的过程中,我们可以直接将栈中元素的 (pre) 值取 (max) 来计算 ([ ext{stk}_{tp-1}, ext{stk}_{tp}))(mathtt{dp}) 值的 (max),也即计算新的 (pre)

这时再维护一个 (mathtt{dp}) 值的前缀 (max),和转移的 (w)(b_x)(mathtt{dp}) 值取 (max) 即可。这就是 (mathcal O(n)) 的了。

( ext{Pigeonhole})

题目描述

鸽子最近成了大忙鸽,它堆积了 (2n) 个事件以待处理。然而,

[ ext{No pigeonhole, no pigeon.} ]

所以鸽子决定鸽掉 (n) 个事件!

为了鸽得更开心,更有意义,它定义鸽掉 (n) 个事件的咕值为这 (n) 个事件重要度 (w) 的最大公约数。现在它想知道鸽掉 (n) 个事件能获得的最大咕值,由于它还有 (n) 个事件需要忙碌,所以这个问题就交给了你。

(nle 10^5,wle 10^{12})

解法

任取一个事件 (x),你会发现答案是 (x) 的因数的概率至少为 (frac{1}{2})

于是随机化一个事件 (x),处理出 (w_x) 的约数,然后求出 (gcd(w_x,w_i)(i eq x)) 贡献给了多少个约数即可。

原文地址:https://www.cnblogs.com/AWhiteWall/p/15476854.html