进度(33/50)
(color{#FF003F}{ exttt {CF504E Misha and LCP on Tree}})
序列上的问题可以二分+hash,直接上树。复杂度 (O((n+m)log n))
评测链接
(color{#FF003F}{ exttt {CF506C Mr. Kitayuta vs. Bamboos}})
首先想到二分答案。
让时间倒流,每个元素有个限制 (lim_i) 表示到某一轮 (a_i<=lim_i)
每次操作变成 (lim_i-=a_i),(lim_i+=p),同时任意时刻都要有 (lim_i>=0),且最开始 (lim_i>=h_i)
发现对于每个元素问题独立,于是分开做。
搞个 (operatorname{map}) 维护下剩余的 (+p) 操作位置及数量,每次二分个位置使得 (lim_i<0),不断取大于这个位置且最小的 (+p) 操作即可。
复杂度 (O((nlog m + mklog mk)log V))
(color{#FF003F}{ exttt {CF512D Fox And Travelling}})
首先可以发现环上的点不可能经过,这告诉我们要往树的方向去想。
对图做类似拓扑排序的东西,出现过的点一定形成了一个森林。其中一些树有根,根是与未经过点相邻的经过了的点,可以证明根只有一个。树上的父子关系相当于是,如果取了一个点的所有儿子,才可以取这个点。
对于有根树,通过简单dp处理出这棵树中取 (0..siz) 个的方案数。
对于无根树,对所有点做一次dp,对应位上值相加。对于 (1leq i < siz),此时的根一定不选,对于 (i) 个点的方案被算了 (siz-i)次,所以 (dp_i/=siz-i)。对于 (i=siz),此时每个点都可以最后一个被选,不用除。
做个背包合并。
(color{#FF003F}{ exttt {CF516D Drazil and Morning Exercise}})
设 (f_x=max_{i=1}^{n}dist(x,i))
所有的 (f_x) 可以换根dp求出。
问题转化成了:树上点有权值, (q) 次询问,给出 (L) ,求满足 (max_{i in S}f_i-min_{i in S}f_i leq L) 的 (S) 中最大的集合大小。
一种想法是每条边都有出现时间区间,线段树分治维护,复杂度 (O(nq log n alpha(n))) ,看起来很大的样子。
考虑 (f_i) 的性质,如果把 (f_i) 最小的点作为根,(forall u=fa_v , f_v=f_u+w(u,v))
证明:
设 (g_i) 表示只考虑 (i) 子树中的点时的 (max dist(x,i)) ,有 (f_i geq g_i)
首先先证 如果 (u) 是 (f_i) 最小的点,(v) 是 (u) 的儿子,那么 (f_v=f_u+w(u,v))
假设 (f_v) 由 (v) 子树内一点 (x) 转移,即 (f_v=g_v=g_x+w(x,v)),那么(f_u geq g_v+w(u,v) geq f_v),与 (u) 是 (f_i) 最小的点矛盾,所以 (f_v=f_u+w(u,v))
由上可知 (f_v=f_u+w(u,v) geq g_x+w(v,x)) ,那就有 (f_u+w(u,v)+w(v,x) > g_x),那么 (f_x=f_u+w(u,v)+w(v,x)=f_v+w(v,x))。
归纳一下就可知 (forall u=fa_v , f_v=f_u+w(u,v))
把所有点按 (f_i) 从大到小的顺序加入,并查集维护下就行了。(O(n log n+nqalpha(n)))
(color{#FF003F}{ exttt {CF521D Shop}})
操作的顺序是123。把 (operatorname{assign}) 转化成 (operatorname{add}) ,再把 (operatorname{add}) 转化成 (operatorname{multiply}) 。
直接按顺序贪心取。
(color{#FF003F}{ exttt {CF526F Pudding Monsters}})
显然有(r-l<=max -min)。枚举左端点,单调栈维护最大最小值。只要如果全局 (max - min - r) 的最小值等于 (-l) ,就在线段树上数最小值个数。
(color{#FF003F}{ exttt {CF526G Spiders Evil Plan}})
先考虑单次询问。发现 (y) 条路径的端点一定是叶子节点,产生的联通块最多会有 (2y) 个叶子。但还是不好做。
考虑一个相似的问题:一棵有根树,选 (k) 个点,最大化这 (k) 个点到根节点路径的并的大小。
选的点肯定是叶子。如果 (k geq) 叶子个数,答案肯定是 (n) 。
否则定义一个点的贡献为 (V_i) 为 (i) 到根节点上没被经过的点的个数。每次选 (V_i) 最大的肯定最优。
性质:每个点一定在其长链顶端的父亲所在长链底端的点被选后被选。
那么 (V_i=dep_i-dep_{fa_{top_i}}),直接贪心。
如果有多次询问,考虑优化上述做法的复杂度。
有一个性质,直径的一个端点端点一定会被选中。
不妨以直径端点为根,那么还要选 (2y-1) 个叶子。预处理下即可。
考虑原问题。若直接用上述做法,可能 (x) 不在联通块内。
有两种策略进行调整
-
删除第 (2y-1) 个点,加入 (x) 的子树内 (V_i) 最大的点。
-
找到 (x) 的祖先中离 (x) 最近的被覆盖的点,删除它子树中被选的一个叶子,加入 (x) 的子树内 (V_i) 最大的点。
发现 (2) 策略不是很好维护。但是如果 (2) 策略比 (1) 策略优,那么 (x) 的祖先中离 (x) 最近的被覆盖的点的子树中只能有 (1) 个被选中的点。
倍增往上跳即可。
复杂度 (O((n+q)log n))
(color{#FF003F}{ exttt {CF528C Data Center Drama}})
条件每个点出入度都是偶数,得出每个点的度数是偶数,与欧拉回路有关。
先说做法,把度数是奇数的点两两连边,如果总边数是奇数,再连个自环,跑欧拉回路,路径上的边隔一个反转。
下面证明这是最优的。
把度数是奇数的点两两连边是显然的。考虑直接跑欧拉回路,并且不反转边。我们称奇点是入度出度都是奇数的点,偶点是入度出度都是偶数的点。
如果总边数是偶数此时图中有偶数个奇点,通过调整(反转一条边),可以使得点全是偶点,满足条件。
如果总边数是奇数,此时图中有奇数个奇点,通过调整(反转一条边),可以使图中只剩下一个奇点,必须进行操作,加个自环即可。
(color{#FF003F}{ exttt {CF536D Tavas in Kansas}})
先跑最短路,每个人肯定是按 (dis) 从小到大取,设 A 的序列是 (t1),B 的序列是 (t2)。
由于总和不变,可以看成 (ans=A-B),A 要最大化 (ans),B 要最小化 (ans)。
这就可以 dp 了。
(f_{i,j}) 表示 A 已经选了前 (i) 个,B 已经选了前 (j) 个,现在是 A 选,从这个状态到选完的答案。
(g_{i,j}) 表示 A 已经选了前 (i) 个,B 已经选了前 (j) 个,现在是 B 选,从这个状态到选完的答案。
(n^3) 转移是显然的。
可以修改状态定义为
(f_{i,j}) 表示 A 已经选了前 (i) 个,B 已经选了前 (j) 个,现在是 A 选且这一步 A 已经选了至少一个点,从这个状态到选完的答案。
(g_{i,j}) 表示 A 已经选了前 (i) 个,B 已经选了前 (j) 个,现在是 B 选且这一步 B 已经选了至少一个点,从这个状态到选完的答案。
考虑转移 (f_{i,j}) 可以转移到 (f_{i-1}{j}) 和 (g_{i,p}) ,其中 (p) 是第一个满足 (t2_p) 没在 (t1_{1..i}) 中出现过的位置,可以简单预处理求出。
(g_{i,j}) 同理。
于是就做完了。
代码中 (t1,t2,f,g) 都是反的(指std::reverse()
评测链接
(color{#FF003F}{ exttt {CF538H Summer Dichotomy}})
先不考虑 (t,T) 的限制,容易发现:如果有解,(n1=operatorname{max}L,n2=operatorname{min}R) 一定满足条件。
加上 (t,T) 的限制,若 (n1+n2<t) 则增大 (n1),若 (n1+n2>T) 则减少 (n2)。
证明:
1.当 (n1<=n2) 时
此时线段两两相交。
假设 (n1+n2<t),设 (cur) 为改变后的 (n1)。
若 (cur<=n2),则原来包含 (n1) 的线段仍包含 (n1),原包含 (n2) 的线段仍包含 (n2),条件仍满足。
若 (cur>n2),因为当 (cur=n2) 时两者等价,必须一个不变,另一个增大(否则必然有不符合条件的),不妨使 (cur) 增大,故上述策略最优。
(n1+n2>T) 的情况同理。
2.当 (n1>n2) 时
此时如果 (n1) 减小,则 (L=n1) 的线段不符合条件,所以 (n1) 只能增大。
如果 (n2) 增大,则 (R=n2) 的线段不符合条件,所以 (n2) 只能减小。
故上述策略最优。
二分图染色搞搞。
(color{#FF003F}{ exttt {CF547D Mike and Fish}})
对于每一行,每一列建一个点,对于点 ((x,y)),在 (x) 和 (y) 之间连边。
显然,形成的图中如果点的度数都是偶数,那么根据欧拉路径定向,一定可以使得要求同一水平线或垂直线上两种颜色的数量相同。
图中一定有偶数个奇数度的点,建一个虚点,向所有度数是奇数的点连边,根据欧拉路径定向,一定可以使得要求同一水平线或垂直线上两种颜色的数量最多相差 (1)。
(color{#FF003F}{ exttt {CF547E Mike and Friends}})
(operatorname{parent tree})上线段树合并裸题
(color{#FF003F}{ exttt {CF555E Case of Computer Network}})
把边双缩点后是一棵树,对于每个要求树上差分做一下。
(color{#FF003F}{ exttt {CF559E Gerald and Path}})
用 (dp_{i,j,d}) 表示考虑了前 (i) 条线段,其中第 (j) 条方向是 (d),且第 (j) 条最靠右。
如果 (i+1) 条线段,向右放置,那么直接转移 (dp_{i+1,*,*} leftarrow dp_{i,j,d}+ min(L_{i+1},P_{i+1,1}-P_{j,d}))
一条线段向左放置的转移:枚举一个 (k) ,表示 (i+1) 到 (k-1) 都向右,(k) 向左,(dp_{k,a,b} leftarrow dp_{i,j,d}+min(L_k,P_{a,b}-P_{j,d})+P_{a,b}-pos_k)。
正确性:所有转移都合法,且可以证明感性理解最优解一定能通过某种策略转移出来。
(color{#FF003F}{ exttt {CF566C Logistical Questions}})
不太懂,先鸽着,求教育(operatorname{/kel})
(color{#FF003F}{ exttt {CF566E Restoring Map}})
设 (f_u) 是距离 (u leq 2) 的集合。
下面只考虑叶子节点数 (geq 3) 的情况。
有个结论:若两点 (u,v) 满足 (|f_u cap f_v|=2),则交中的两个节点间有边,且所有连接非叶子节点的边都会出现。
证明:
1.(f_u) 一定是个联通块,(f_u cap f_v) 也是个联通块,两个点组成联通块所以两个点间有边。
2.所有连接非叶子节点的边都会出现:分别取这两个点的任意一个邻居即可。
所以我们可以先用 (operatorname{bitset}) 搞出所有连接非叶子节点的边。
对于叶子节点,如果它 (f_u) 中的点的邻居集合与 (f_u) 相同,则这两点间有边。读者自证不难。
同样用 (operatorname{bitset}) 优化。
(color{#FF003F}{ exttt {CF568C New Language}})
显然和 ( exttt{2-sat}) 有关。设输入中的串是 (s),答案串是 (t)。
假设我们知道了 (operatorname{lcp}(s,t)),那就可以按顺序枚举 (operatorname{lcp}(s,t)) 后每个位置放 (V) 还是 (C),暴力染色判断就行了。
从大到小枚举 (operatorname{lcp}(s,t)),用 ( exttt{2-sat}) 判断是否可行即可。
(color{#FF003F}{ exttt {CF568E Longest Increasing Subsequence}})
考虑LIS问题的经典 (O(nlog n)) 解法,(dp_i=max_{a_j<a_i}(dp_j)+1), (operatorname{Fenwick tree}) 优化。
回到本题,首先可以发现不重复选这个限制是没有意义的,因为重复选了对答案没有贡献。
一种 naive 的想法是对每个空缺位枚举选哪个数,dp的同时用 (operatorname{Fenwick tree}) 维护数组 (maxval),(maxval_i=max_{dp_j}(a_j<=i))。复杂度是 (O(n log n + mklog n))。冷静分析一下发现瓶颈在每次都要更新 (maxval) 数组,又发现如果只在 (k) 个空缺位置暴力更新复杂度是对的。
对于 (a_i=-1) 的位置,对 (maxval) 数组求前缀 (max),枚举当前位选了什么数,(dp_i=max_{j in S} maxval_{j-1}+1)。
对于 (a_i ot=-1) 的位置,(dp_i=maxval{a_{i-1}}+1),其中 (maxval) 有两部分,分别是 (a_i=-1) 和 (a_i ot=-1)的贡献,同时维护 (operatorname{Fenwick tree}) 。
考虑如何构造方案,
如果当前位不是空缺位,直接到 (dp) 时记录的最优转移点。
否则 (a_i=max_{x in S,x<last}x) ,并尝试向前找到一个非空缺位且满足 (dp_j+1=dp_i (a_j<a_i)),如果没找到,就找离 (i) 最近的空缺位,递归地构造。
容易证明这样一定可以构造出最优解。
对于本做法有点卡常,需要精细地实现程序。复杂度 (O(nlog n + mk)),代码
(color{#FF003F}{ exttt {CF571D Campus}})
考虑只有1,3,5操作,带权并查集可以快速维护,每次合并新建节点,路径压缩的时候把权值算一下。
如果有2,4操作,那么离线下来,先做2,4,算出每个点最后被清空的时间,减一减。
(color{#FF003F}{ exttt {CF573E Bear and Bowling}})
考虑贪心
定义每个点的贡献为 (k_i*a_i+suf_i) ,其中 (k_i) 表示位置 (i) 之前被选的数的数量,(suf_i) 表示位置 (i) 之后被选的数的 (sum a_i)
每次选贡献最大的点,历史最大值就是答案。
( exttt { 证明 by } exttt {c} color{#FF003F}{ exttt {z_xuyixuan}})
式子是个斜率优化的形式,想到分块维护凸壳,直接凸壳上二分的话,复杂度会带一个 (log),由于斜率具有单调性,单调队列搞搞就好了。
(color{#FF003F}{ exttt {CF575A Fibonotci}})
线段树维护矩阵乘法。
(color{#FF003F}{ exttt {CF576D Flights for Regular Customers}})
bitset优化矩阵乘法。复杂度 (O(frac{n^3m log d}{w}))
(color{#FF003F}{ exttt {CF576E Painting Edges}})
线段树分治。边查询边加入修改。
(color{#FF003F}{ exttt {CF578E Walking!}})
可以发现问题等价于将原串划分成尽量少的 (L,R) 交错的子序列。
先贪心地划分,再考虑合并, 简 单 分类讨论即可。
(color{#FF003F}{ exttt {CF582E Boolean Function}})、
建表达式树,FWT优化dp。
(color{#FF003F}{ exttt {CF585E Present for Vitalik the Philatelist}})
枚举集合的 (gcd),乘上与 (gcd) 互质的数的个数。这两个都莫比乌斯反演一下,反演出来是 (f_i=sum_{x|i}a_x) 的形式。
直接调和级数搞搞,或者 (operatorname{Dirichlet}) 前缀和算下。复杂度 (O(Vlog V)) / (O(Vlog log V))
(color{#FF003F}{ exttt {CF585F Digits of Number Pi}})
把 (S) 的所有长度为 (lfloor frac d2 floor) 的子串建个 ACAM,数位dp。
(color{#FF003F}{ exttt {CF587D Duff in Mafia}})
二分答案+(operatorname{2-sat})
(color{#FF003F}{ exttt {CF587F Duff is Mad}})
考虑如何暴力,建 (operatorname{ACAM}),查询一个点在 (operatorname{trie}) 树上到根的路径上的所有点在 (operatorname{fail}) 树上到根节点中满足 (l leq id leq r) 的总和。
有两种做法。
1.对一个点在 (operatorname{trie}) 树上到根的路径上的所有点打标记,在 (operatorname{fail}) 树上算子树和,统计答案。单次可以处理关于这个串的所有询问,复杂度 (O(sum len+n))
2.对一个点在 (operatorname{trie}) 树上到根的路径上的所有点计算其在 (operatorname{fail}) 树上到根的答案,数据结构维护。单次可以一个询问,复杂度 (O(len))
其中 (2) 方法也等价于把 (l,r) 中的点在 (operatorname{fail}) 树上做子树加,查询一个点在 (operatorname{trie}) 树上到根的路径上的所有点的权值和。
考虑根号分治。
对于 (lenleq S) 的串用 (2) 方法,对于 (len>S) 的串用 (1) 方法。
如果 (2) 方法中的数据结构使用 (operatorname{Fenwick tree}) ,复杂度 (O(nsqrt{nlog n}))
如果 (2) 方法中的数据结构使用 (O(sqrt n)) 区间加,(O(1)) 单点查询的分块 ,复杂度 (O(nsqrt{n}))
(color{#FF003F}{ exttt {CF603E Pastoral Oddities}})
结论:一个图合法,当且仅当每个连通块的大小都是偶数。
证明:
必要性:度数的奇偶性,读者自证不难。
充分性:
下面只考虑图连通的情况。
当 (n=2) 时,显然成立。
当 (n>2) 且 (n) 是偶数时,假设 (n-2) 成立,加入两个点。
如果两个点间有边,不取这两个点与原连通块间的边,取两点之间的边即可;
如果两个点间无边,将原连通块中与这两个点相连的点之间的边不取,取这两点与原联通块的边即可。
归纳可证原命题成立。
简单 (LCT) 维护。
(color{#FF003F}{ exttt {CF605E Intergalaxy Trips}})
先说做法。
(E_x) 表示到目前为止的答案,显然 (E_x) 不会从更大的地方转移。(E_x = sum_{i}E_iP_{x,i}prod_{j<i}(1-P_{x,j}))
直接做的话,问题在于你不知道 (E) 的大小关系。考虑动态维护,每次找个答案最小的点,显然它不会被其他点更新,用它去更新其他点,复杂度是 (O(n^2))。
每次 (E_x) 并不是真实的答案,可能与它的每条边都不存在,要除 (1-prod_i (1-P_{x,i}))
唯一需要证明的地方是 (E_x = sum_{i}E_iP_{x,i}prod_{j<i}(1-P_{x,j})),可能还有一种策略是并不全选比 (E_x) 小的,只选较小的几个。
证明:
假设 (x) 已经从若干个点处转移,现在考虑加入 (i) 点,满足 (frac{E_i}{1-prod_{j}(1-P_{i,j})}leq frac{E_x}{1-prod_{j}(1-P_{x,j})})
设 (P=P_{x,i},M=prod_{j}(1-P_{x,j}),C=frac{E_i}{1-prod_{j}(1-P_{i,j})},0leq P,Mleq 1)
满足的条件是 (Cleq frac{E_x}{1-M})
原答案是 (frac{E_x}{1-M}),加入后答案是 (frac{E_x+C*P*M}{1-M+M*P})
需要证明 (frac{E_x+C*P*M}{1-M+M*P}leq frac{E_x}{1-M})
(ecause Cleq frac{E_x}{1-M} leqfrac{E_x}{1+M})
( herefore C+C*Mleq E_x)
( herefore C*M*P+C*M^2*Pleq E_x*M*P)
两边同时加 (E_x-E_x*M) ,(E_x-E_x*M+C*M*P+C*M^2*Pleq E_x*M*P+E_x-E_x*M)
整理得:((E_x+C*P*M)*(1-M)leq E_x(1-M+M*P))
( herefore frac{E_x+C*P*M}{1-M+M*P}leq frac{E_x}{1-M})
所以加入 (i) 更优。
而显然从期望答案更大的点转移是不优的,所以最优策略是从答案比 (x) 小的所有点转移。
(color{#FF003F}{ exttt {CF611G New Year and Cake}})
设点集为 (p_{1..n})(逆时针)。答案等于 总面积*(n(n-3)-)每种方案中较小的那块的面积*(2)。
可以用 (operatorname{two-pointers}) 对于每个点算出满足 面积<=总面积/2 的最远的点,设它是第 (k) 个点。
考虑如何快速计算确定了 (k) 时的答案。
简单预处理即可,复杂度 (O(n))。
(color{#FF003F}{ exttt {CF626G Raffles}})
显然的贪心:每次取使答案最大的。可用堆做到 (O(tlog n))
可以证明,每次修改后,策略最多只会变化 (1) 次。(读者自证不难)
用两个堆即可维护。