赛时做出了 ABCDE,没有做出 FGH;目前已补掉了 F,尚未补掉 G,H。
令 b i b_i bi 为 a i a_i ai 所含质因子 2 2 2 的个数, c i = a i 2 b i c_i=\frac {a_i} {2^{b_i}} ci=2biai。不难发现,调整过程等价于将一共的 S = ∑ i = 1 n b i S=\sum_{i=1}^n b_i S=∑i=1nbi 个质因子 2 2 2 重新分配给所有的 c c c,使得所有值之和最大。
根据贪心策略,将 S S S 全部分配给最大的 c c c 即可。
不难发现,最少删除次数就是 abc
以子串形式出现的次数。于是,我们只要在询问过程中,动态更新这个值即可。
时间复杂度 O ( ∑ ( n + q ) ) O(\sum (n+q)) O(∑(n+q))。
为方便叙述,令 b i = 1 b_i=1 bi=1 当且仅当 a i a_i ai 为质数, b i = 0 b_i=0 bi=0 当且仅当 a i = 1 a_i=1 ai=1, b i = − 1 b_i=-1 bi=−1 当且仅当 a i a_i ai 为合数。
看到下标为等差数列的问题,不难想到将 a a a 分成独立的 e e e 类,第 i i i 类为 { b i , b i + e , ⋯ } \{b_i,b_{i+e},\cdots\} {bi,bi+e,⋯}。于是,问题转化为: 对于一个固定的序列 c c c,求其有多少个子区间不包含 − 1 -1 −1 且和为 1 1 1。显然,将 c c c 中所有值为 − 1 -1 −1 的位删去,再对每个分裂出的区间做前缀和,最后再用桶扫描一遍计算对答案的贡献即可。
时间复杂度 O ( ∑ n ) O(\sum n) O(∑n)。
首先,图中不会有环。
其次,令 S i S_i Si 为第 i i i 个连通块所包含的点集,那么对于每个 S i S_i Si 在其内部连成一个菊花图必定最优。因此,答案就是 max i { S i } − 1 \max_i \{S_i\}-1 maxi{Si}−1。于是,问题转化为: 如何构造图,使其最大的连通块最大。
依次扫描每一条边 ( x , y ) (x,y) (x,y),并分类讨论:
可以发现,当前的 c n t cnt cnt 就是我们可以随意钦定的边数;不难想到,用这 c n t cnt cnt 条边将前 c n t + 1 cnt+1 cnt+1 个最大的连通块连接起来,即可最大化 max i { S i } \max_i \{S_i\} maxi{Si}。
并查集维护即可。时间复杂度 O ( n 2 ) O(n^2) O(n2)。
若使用权值线段树维护各个连通块的大小,并每次通过线段树上二分求出答案,则总复杂度可以被优化到 O ( n log n ) O(n \log n) O(nlogn)。
考虑 dp \text{dp} dp。
令 x i x_i xi 表示,看了 s [ 1 , i ] s[1,i] s[1,i],使其中不存在 a
的最少删除次数。
令 y i y_i yi 表示,看了 s [ 1 , i ] s[1,i] s[1,i],使其中不存在子序列 ab
的最少删除次数。
令 z i z_i zi 表示,看了 s [ 1 , i ] s[1,i] s[1,i],使其中不存在子序列 abc
的最少删除次数。
转移如下:
边界: x 0 = y 0 = z 0 = 0 x_0=y_0=z_0=0 x0=y0=z0=0。
答案: z n z_n zn
每次修改都跑一遍 dp \text{dp} dp,则总复杂度 O ( q n ) O(qn) O(qn),无法通过。
采用矩阵表示上述转移,并使用线段树维护矩阵乘法,则时间复杂度为 O ( q log n × 3 3 ) O(q \log n \times 3^3) O(qlogn×33),可以通过本题。
我竟然没有发现我的做法的复杂度是正确的!!1
令 w i = popcount ( a i ) w_i=\text{popcount}(a_i) wi=popcount(ai), W = 59 W=59 W=59。我们在 [ 0 , W ] [0,W] [0,W] 中枚举一个 x x x,表示区间最值的 w w w 均为 x x x。
为方便叙述,令 i i i 为优秀位置,当且仅当 w i = x w_i=x wi=x。同时,令 t i t_i ti 表示 [ i , r ] [i,r] [i,r] 中 a a a 最大的位置的 w w w 是否为 x x x 以及 a a a 最小的 w w w 是否为 x x x——若均满足则 t i = 2 t_i=2 ti=2,只满足一个则 t i = 1 t_i=1 ti=1,否则 t i = 0 t_i=0 ti=0。
考虑从左往右扫描序列(令当前扫描到了 r r r),并使用单调栈+线段树维护 t t t。具体来说,我们使用一个表示最小值的单调栈,维护一个递增序列;每当新看到一个数的时候,我们先进行弹栈,并对于每个弹出的值进行区间加 1 1 1 或区间减 1 1 1(因为一个新的区间最小值替代掉了原来的区间最小值,如果优秀的替换了不优秀的那么区间加 1 1 1,如果不优秀的替换掉了优秀的那么区间减 1 1 1)。另外也要用一个表示最大值的单调栈进行同样的处理。不难发现,这里只要求维护区间修改,查询区间中 2 2 2 的数量,线段树显然可以胜任。
那么这个复杂度是什么的呢?我赛时一直以为是 O ( n log n log M ) O(n \log n \log M) O(nlognlogM) 的,实则不然。下面便是复杂度分析:
因此,总时间复杂度是 O ( n ( log n + log M ) ) O(n(\log n+\log M)) O(n(logn+logM))。卡常后可过本题。