联合省选记录
2020
2023/3/24
树状数组的高级用法!
离线,温度离散化。打的时候两方肯定能上就上,能量消耗就是 \(2\min(\sum e_\text{冰},\sum e_\text{火})\)(\(e\) 是能量),别被题面吓到了。
显然温度一定取某个战士的温度,因此温度的取值只有 \(O(Q)\) 种。
于是维护冰/火阵营在温度等于 \(i\)(离散化后)时能上场的能量值和 \(t[0/1][i]\),易得加入/撤回一个冰系战士就是 \(t[0]\) 后缀加/减,加入/撤回一个火系战士就是 \(t[1]\) 前缀加/减,易用线段树、树状数组等数据结构维护。
那么答案就是 \(2\max_{i}(\min(t[0][i],t[1][i]))\),考虑这个东西怎么求。
容易发现随着 \(i\) 增加,\(t[0][i]\) 单调不降,\(t[1][i]\) 单调不增,那么易得 \(\min(t[0][i],t[1][i])\) 单峰。
于是可以二分 \(t[0][i]-t[1][i]\) 最接近 \(0\) 的点(类似导数),\(\le 0\) 求一个,\(\ge 0\) 求一个,比一比谁更优,然后再二分出一个等于答案的最大位置作为最终温度。
非常合理,直接树状数组/线段树 + 二分是 \(O(Q\log^2 Q)\) 的,寄寄寄。
考虑我看了题解新学的 树状数组上倍增:
显然二分换成倍增没啥问题,同事我们知道,树状数组每个节点 \(p\) 维护 \(T[p]=\sum_{i=p-lowbit(p)}^pa[i]\)。
那么我们从 \(0\) 开始直接倍增位置 \(pos\)。枚举到第 \(i\) 位(倒序)时,\(\le i\) 位上显然都是 \(0\)。
那么如果要使第 \(i\) 位等于 \(1\),则相当于查询 \(pos+2^i\) 的结果。但是这个时候,\(lowbit(pos+2^i)\) 必然等于 \(2^i\),因此相当于 \(T[p]\) 就储存了 \(pos\) 到 \(pos+2^i\) 的信息,直接加上去即可得到答案。
忽略了一大车细节,但是不难实现。
2023/3/25
感谢jlq一语点醒!
感谢jlq两次一语点醒!
感谢jlq很多次一语点醒!
做法:摁推式子。
首先把多项式拆开,每次只考虑一项。设当前为第 \(c\) 项:
那么好了。最后:
\(\begin{Bmatrix}n\\k\end{Bmatrix}\) 是第二类斯特林数。
\(O(m^2)\) 预处理第二类斯特林数,\(O(m^2)\) 统计。
2023/3/24
好久之前做的了,再做一遍。
先开一个桶记录一下每对 \((i,j)\) 传了多少次。然后一眼状压,但是 naive 的做法显然要把每个数的位置塞进状态,非常不行。
这种东西,一般考虑拆贡献。这里的贡献非常良心,是可减的。具体的,若 \(p_i\) 表示第 \(i\) 个信号站的位置,则有 \(i \to j\) 的贡献为:
于是当前贡献就和前面放的顺序就没关系了,直接 \(dp[S]\) 表示已经依次放完了集合 \(S\) 中的信号站的最小代价。考虑往 \(S\) 中加一个数 \(i\) 的过程(由于 \(S\) 的大小可知,则 \(p_i\) 已知)。
遍历所有 \(j\),考虑 \(i\) 与 \(j\) 之间通信时 \(i\) 的贡献:
-
若 \(j\) 已在 \(S\) 中,则 \(p_j<p_i\),则 \(i \to j\) 的贡献为 \(k\times p_i\), \(j\to i\) 的贡献为 \(p_i\)。
-
若 \(j\) 不在 \(S\) 中,则 \(p_j>p_i\),则 \(i \to j\) 的贡献为 \(-p_i\), \(j\to i\) 的贡献为 \(k \times p_i\)。
然后无脑转移,时间复杂度 \(O(m^22^m)\),卡卡常吸个氧能过,进行重度预处理加上一定的空间优化可以将时间复杂度降为 \(O(m2^m)\),空间复杂度 \(O(\text{能过})\)。
这个东西,或许应该叫“贡献提前计算”?
和下面的P7519 [省选联考 2021 A/B 卷] 滚榜有着异曲同工之妙!
2023/3/24
01-trie 的高级用法!
自底向上求答案,每个节点 \(u\) 维护子树中 \(v_{c_{i}}+d(u,c_i)\) 的 01-trie,并逐层向上合并。类比线段树合并,这部分是 \(O(n\log n)\) 的。
合并时,我们发现要对 \(u\) 的 01-trie 进行全局加一,然后进行全局异或和。接下来进入 01-trie 高级用法。
首先我们以先低位后高位的顺序插入数,然后考虑 +1 这个操作意味着什么。
对于单独的一位来说,+1 等价于 xor 1,就是使这一位 01 翻转,容易通过交换节点的 01 子树实现。
而对于进位来说,其实就是对上一位交换之前的 1 子树进行递归处理。
全局异或的话顺便维护一下当前子树内异或和就行了。
我又不开 long long 见祖宗了!
递归处理的代码非常简洁!
2023/3/24
水一水
结论是只要当前合法前缀的和 \(\ge 0\),就操作一次。
证明很简单:若中间操作了一次前缀和是负数的,那么不操作它显然会使答案更优。
2023/3/26
点分治点分治点分治点分治点分治点分治点分治点分治点分治点分治
考虑询问的实质是问与 \(x\) 距离为 \(k\) 的点有多少个,转化为有多少条以 \(x\) 为端点的、长为 \(k\) 的路径。
考虑点分治。离线后把询问挂在 \(x\) 上,每次处理经过分治中心的路径。可以处理出当前所有点的深度 \(dep\),并扔到桶里记录深度为 \(i\) 的点有多少个。乱搞一通,实在不行多写几个 dfs,就是容易卡常(我)。
多测要清空。
2023/3/24
再水一水
考虑能取到不同值的位置,显然有 \(L,R,A,B,L-1,R+1,A-1,A+1,B-1,B+1,0,-10^9,10^9\)。
取 \(0\) 是因为有 绝对值最小 这个东西。
然后大力扔进数组离散化,条件相当于区间异或一个数,直接差分就行。
最后遍历所有的位置,按照题意取最优点就行。
如果点加的不全,可能会有 35,75,80,85 等分数/fn
2023/3/27
只会贺题了。。猜猜它为啥是 d2t3?有技术的
\(|i-j|\) 这个路径长度看起来非常正常。但是其实它给了我们一个极其显然但是及其重要的转化:所有非必须走的路径 \((u,v)\)(这里是 \(u<v\)。对于 \(u>v\) 的情况相应对称) 都能拆成 \((u,u+1),(u+1,u+2),\dots,(v-1,v)\) 而总贡献不变。
(其实不一定是长度为 \(1\) 的路径。只要是 \(u,v\) 中间取断点然后分成好几条的都成立。)
假设当前考虑朋友 \(I\)。相当于在无向图中找出 \(s\) 到 \(I\) 必须经过一些边时的最短路。
“必须经过”长得非常像欧拉路径/回路。显然回路的判定条件更简单我们选择转化成欧拉回路的模型。
回忆无向图欧拉回路的判定。图存在欧拉回路当且仅当:
-
\(\forall i,2|deg_i\)。
-
图联通
首先,为了使其形成回路,我们先把 \((I,s)\) 这条边加入必须走的边,意义显然。然后我们先把所有必须走的边加入一个没有边的图(用来搞欧拉回路)中,算出每个点的 \(deg\)(度数)。
先把此时 \(deg_i=0\) 的点抠掉(反正不用经过)。
首先来解决第一个限制:\(\forall i,2|deg_i\)。
显然 \(deg_i\) 为奇数的点有偶数个。将这些点按照编号从小到大排序后(设排序后序列为 \(a\)),加入边 \((a_{2k-1},a_{2k})\)。可通过上面的结论转化成相邻点(去除 \(deg=0\) 后)之间的路径。这样在满足了 \(deg_i\) 的限制的同时,使得联通块数尽量的少,照应了第二个限制的解决:图联通。
要使图联通,就是扣出端点不在同一个联通块内的边进行最小生成树。显然又可以通过上面的结论转化成相邻的点(去掉 \(deg=0\) 的点后)之间的边做最小生成树。直接 \(\text{Kruskal}\)。
为保证 \(deg_i\) 的限制,每条生成树上的边要算两次。
最后就是并不需要知道欧拉回路长啥样,算权值和就行了。
甚至不用知道图长啥样,只维护并查集和 \(deg\) 就行了。
复杂度 \(\mathcal{O}(n^2\log n+m)\)。
并不难写。
最小生成树没按边权排序有70/jy
2021
2023/3/21
自己想了一个及其恶心的 \(O(n\log n)\),因为过于恶心没写,放一个题解做法:
首先 \(a\) 面和 \(b\) 面混一起排序,最终正面的集合一定是一个排完序之后的子序列。答案即为最右边的值减去最左边的值。
可以转化为一段连续区间 \([l,r]\),满足:
- \([l,r]\) 中每个卡牌至少出现一面。
- 不在区间内的 \(a\) 面数量 \(\le m\)。
双指针。瓶颈在排序。
\(O(n\log n)\)
uoj 都过了,正确性一定是对的。/hanx
2023/3/21
首先随便找到一种方案是 naive 的,直接第一行第一列全放 \(0\),其他的顺序推过去。
显然大概率无法满足 \(\forall a_{i,j}\in[0,10^6]\),因此考虑调整方案。
首先,对于一行来说,我们给它依次 +1,-1,+1,-1.... 的话显然能满足 \(b\) 的限制,对列来说同理。
设 \(c_i\) 为对第 \(i\) 行进行了多少次这样的操作,\(d_i\) 为对第 \(i\) 列进行了多少次这样的操作。
于是我们转化成了 \(0 \le a_{i,j}\pm c_i \pm d_j \le 10^6\)。
问题是这样会出现“和分约束”这种我不会的东西,因此我们换成这种形式:
对行来说:
对列来说:
这样保证了每个位置对它贡献的 \(c_i\) 与 \(d_j\) 均异号,保证了全是差分约束。
哦,再给一个但凡有解这样做一定能得到解得证明:确定第一行和第一列就可以确定整个矩阵(根据 \(b\) 顺推),先对行操作再对列操作可以达到任意我们想要的第一行与第一列的状态,因此能得到所有可能的矩阵。
跑 Bellman-Ford,spfa 卡常。
但是还是卡卡卡卡卡常。
2023/3/22
图论困难。
瞄了一眼题解只看到 Floyd ,后面推出来了,真是奇迹!
不管删边,考虑一个点对 \([u,v]\) 怎样才能有贡献。
若考虑 \(v\) 对 \(u\) 的贡献(即 \(f(u,G)\) 中 \(v\) 会使 \(cnt+1\)),则有以下结论:
- \(v\) 对 \(u\) 有贡献,当且仅当存在环 \(C\),满足 \(u,v\in C\) 且环中所有节点编号 \(\ge v\)。
成环显然,后面那条是因为如果存在 \(u'<v\)(编号),则在算 \(u'\) 的时候就会把 \(u'\) 删掉,\((u,v)\) 和 \((v,u)\) 之间一定有一个不连通。
而整个图的答案就是 \(v\) 对 \(u\) 有贡献的数对 \([u,v]\) 的数量。
此时我们可以从大往小加点动态维护点对连通性。对 Floyd 的本质理解到位的话就易得:把第一层枚举倒过来就行了。
然后在第一层枚举中枚举到 \(v\) 的时候枚举 \(u\),判断是否 \((u,v)\) 和 \((v,u)\) 均可达。
接下来考虑删边。容易发现 \([u,v]\) 不再有贡献当且仅当删完边后不存在上述环了。
等价于 \((u,v)\) 或 \((v,u)\) 中有一个不连通,那么考虑处理所有 \((u,v)\) 不连通的最早时间 \(t[u][v]\)。
考虑刚刚 Floyd 的过程,我们会把 \((i,k)\) 和 \((k,j)\) 两条路径接起来。
若现在已知 \(t[i][k]\) 与 \(t[k][j]\),则易得 \(t[i][j]=\max(t[i][j],\min(t[i][k],t[k][j]))\)。
其中 \(t[i][k],t[k][j]\) 取 \(\min\) 是因为只要有一条断了,整条就断;\(t[i][j]\) 取 \(\max\) 是因为只要有一条没断,整条就不断。可类比成串并联理解。
然后就好了。最后我们发现若记 \(T[u][v]=\min(t[u][v],t[v][u])\)(一条断整条断),则数对 \([u,v]\) 对 \(f(G_i)\ \ (i<T[u][v])\) 有贡献。
于是扔到差分数组里做一个后缀和就行了。
码量奇短,主程序只有 \(<0.5K\)。
2022/2/11
开桶记录数的个数,\(O(n\ln n)\) 扫倍数对。
2023/3/22
我不会数据结构我不会数据结构我不会数据结构我不会数据结构我不会数据结构我不会数据结构我不会数据结构
首先使 \(t_{P_{i}}=i,w_i=t_{w_i}\),也即把 \([P_1,P_2,\dots P_c]\) 映射到 \([1,2,\dots,c]\) 上,\(w_i\) 同时对应改变。
举个例子就是 \(P=[2,3,1],w=[2,1,3,3,2,1,3]\) 变为 \(P=[1,2,3],w=[1,3,2,2,1,3,2]\)(样例)。
这样询问就转化为 \((u,v)\) 路径上最大的 \(ans\),使得 \(1,2,\dots,ans\) 在路径上依次出现。
预处理 \(f1[u][i]\) 表示从 \(u\) 开始往上走依次经过 \(w_u,w_u+1,\dots w_u+2^i\) 后的终止节点,\(f2[u][i]\) 表示从 \(u\) 开始往上走依次经过 \(w_u,w_u-1,\dots w_u-2^i\) 后的终止节点。
每个询问可以拆成 \((u,lca)\) 与 \((lca,v)\) 两部分。对于 \((u,lca)\) 来说,起点已经固定,可以先找到 \(u\) 上面第一个 \(1\) 的位置,然后从这个位置开始直接倍增跳 \(f1\) 并记录答案。
但是对于 \((lca,v)\) 来说,起点并不固定,考虑二分答案 \(x\),找到 \(v\) 上面第一个 \(x\) 的位置,从这个位置开始倍增跳 \(f2\),如果能和 \((u,lca)\) 的最后一个数接起来就可行。
找每个点上第一个 \(1\) 可以预处理搞。具体的,维护 \(cur[i]\) 表示从根节点到当前点 \(u\) 的链上第 \(i\) 种颜色最后一次出现的位置。则 \(u\) 上第一个 \(1\) 即为 \(cur[1]\)。
这种方法同时也能预处理出 \(f1[u][0]=cur[w_u+1],f2[u][0]=cur[w_u-1]\)。然后在外面倍增即可预处理出 \(f1,f2\)。
但是找到 \(v\) 上面第一个 \(x\) 的位置不好预处理。考虑离线询问,把 \((lca,v)\) 的询问挂在 \(v\) 上,同样维护 \(cur\) 就能在 dfs 到 \(v\) 的时候每次直接获得 \(v\) 上面第一个 \(x\) 的位置。
注意细节,没有卡常/hanx。
2023/3/21
我这是第几次只差想到最后一步就过了的?
\(n \le 13\),果断状压。
首先我们要求的是 排列的方案数! 因此在滚榜过程中,我们使当前的 \(b\) 最小,可以使后面可操作性最大,从而达到最多的方案,同时避免重复计数。
具体的,若已经确定最终的排列 \((p_1,p_2,\dots,p_n)\),可以这样构造 \(b\):
-
若 \(a_{p_i}\ge a_{p_{i-1}}\),则 \(b_i=b_{i-1}\)。
-
若 \(a_{p_i} < a_{p_{i-1}}\),则 \(b_i=b_{i-1}+a_{p_i}-a_{p_{i-1}}\)。
此处忽略了部分细节(大小相等看编号),意会即可。
此时可以直接 \(O(n! \times n)\) 枚举排列并构造 \(b\),若 \(\sum b\le m\) 则该排列可行(多出来的部分直接加到 \(b_n\) 上没有影响), \(60\) 分。
考虑暴力 \(dp\),一般人一眼能看出 \(dp[S][i][j][k]\) 表示状态 \(S\) 下,当前榜一是 \(i\),\(b_i=j\),已经用了 \(k\) 道,\(O(2^nn^2m^2)\),过不去。
考虑贡献提前计算:设差分数组 \(c_i=b_i-b_{i-1}\)。那么有 \(\sum_{i=1}^nb_i=\sum_{i=1}^nc_i*(n-i+1)\)。
显然根据上面分析,\(c_i\) 只与 \(a_i\) 和 \(a_{i-1}\) 有关,因此我们不用再把 \(b_i\) 放到状态里,\(k\) 也可以改写成当前 \(c_i\) 的贡献和。
因此可以变为 \(dp[S][i][k]\),转移大概长这样:
\(val(a_i \to a_j)\) 表示 \(i\) 后面接 \(j\) 的 \(c\) 的值,可以提前分讨预处理出来。
啊对对对,\(O(2^nn^2m)\),我看看我会不会被卡常。
没有卡常,但是 不开long long 见祖宗了!
2023/3/21
听说是个乱搞暴力题,于是写了一个乱搞暴力过了,接下来证一证复杂度。
先给 \(a_i\) 升序排序。
做法:从大往小枚举 \(a_k\),若当前答案 \(\ge a_k\) 就终止枚举。
确定 \(a_k\) 后,搞出 \(b\) 数组使得 \(b_i=a_i \mod a_k (i \ne k)\),此时在 \(b\) 中选两个数 \(b_i,b_j\),显然 \(b_i+b_j\equiv a_i+a_j \pmod{a_k}\),且分为以下两种情况:
- \(b_i+b_j <a_k\)
此时先给 \(b\) 排序,从小往大枚举 \(b_i\),双指针使 \(b_j\) 不断左移,每次都算一算最优的。
- \(b_i+b_j \ge a_k\)
因为 \(b_i\le a_k-1\) 且 \(b_j\le a_k-1\),所以 \(b_i+b_j \le 2a_k-2\),这种情况怎么取贡献都是 \(b_i+b_j-a_k\),直接取最大的两个 \(b\)。
看起来是 \(O(n^2\log n)\),但是其实复杂度有保证,关键就是若当前答案 \(\ge a_k\) 就终止枚举。
复杂度证明:
(参考 @I_am_Accepted)
设最终答案是 \(ans\),显然只有 \(a_i >ans\) 的数才会被算到。
设 \(>ans\) 的数是 \(a_p,a_{p+1},\dots,a_n\)。
那么首先有 \(a_p<a_{p+1}<\dots<a_n\)(相同模数没必要多次计算,去重)。
因为 \(ans\) 的最优性,一定有 \(\forall i \in[p,n-2]\),满足 \((a_i+a_{i+1})\mod a_{i+2}\le ans\)。
而由 \(a_i <a_{i+2}\ ,\ a_{i+1}<a_{i+2}\),有 \(a_i+a_{i+1}<2a_{i+2}\)。
因此 \((a_i+a_{i+1})\mod a_{i+2}=a_i+a_{i+1}\) 或 \(a_i+a_{i+1}-a_{i+2}\),均 \(\le ans\)。
合并一下就是 \(a_i+a_{i+1}-a_{i+2} \le ans\)。
于是 \(a_i+a_{i+1}-2ans \le a_{i+2}-ans\),即 \((a_i-ans)+(a_{i+1}-ans) \le (a_{i+2}-ans)\)。
代换 \(f_i=a_i-ans\),因为我们只关注 \(a_i>ans\),所以 \(f_i\le 1\)。
代入得 \(f_i+f_{i+1}\le f_{i+2}\),意味着 \(f\) 增长得比斐波那契数列还快,即指数级增长。
又因为 \(f\) 的值域差不多是 \(10^8\),那么相当于 \(n-p=O(\log(10^8))\)。
于是总复杂度就是 \(O(n\log n\log 10^8)\)。
2022
2023/3/6
小模拟,eezz。
2023/3/7
谔谔
考虑一条链的第一问,计算钦定这条链上所有点权都 \(\in [l,l+K]\) 且最小值 \(=l\) 的方案数。
显然可以先容斥转化为 $\ \ $ 所有点权都 \(\in [l,l+K]\)的方案数 $\ \ $ 减去 $\ \ $ 所有点权都 \(\in [l+1,l+K]\)的方案数。
设 \(f(l,r)\) 表示所有点权都 \(\in [l,l+r]\)的方案数,那么对于这条链,答案就是 \(\sum_lf(l,l+K)-f(l+1,l+K)=\sum_lf(l,l+K)-\sum_lf(l+1,l+K)\)。
现在考虑求 \(\sum_lf(l,l+K)\)。
首先,对于一个点 \([l_i,r_i]\),它能取的数的个数为 \(| [l_i,r_i] \cap [l,l+K]|\)
当 \([l,l+K]\) 右移一位变为 \([l+1,l+K+1]\) 时,一个点能取的数个数只会有 +1,不变或者 -1 三种状态。
于是移动这个区间的时候,每个点状态都不变的值域段有 \(O(n)\) 段。
每一段中一个 \(l\) 的贡献就是 $\prod(a_i \pm l) $,是一个关于 \(l\) 的多项式。
于是一段连续值域就相当于一个多项式的区间的值的和,转化为多项式前缀和,进行一个拉格朗日值的插。
那对于第二问,就是把 \(a_i \pm l\) 变成 \(a_i+xl+yl^2\),变成一个二次的多项式,再插值复杂度仍是 \(O(n)\)。
Bonus:其实不用真的把多项式求出来,可以直接dp出一个点值。
BBounus:可恶的卡常。
end。
2023/3/11
自己只能想到 \(O(m^2)\) 的费用流了,一写还出现了负环/ng,而且写挂了。。
寄寄寄
考虑性质 C:
直接把每个消息之间连有向边,有边 \((u,v)\) 表示消息 \(u\) 放在消息 \(v\)上面能产生贡献。
如果是 DAG 的话就万事大吉了,直接跑最小路径覆盖就行。
但是寄了,环一大堆。
但是由于性质 C,如果成环了则必定有:
-
环里没有学术信息
-
环里全是
loushang或全是louxia。
以上两条性质显然。
由于题目中反复强调的重要性质,我们可以不断地断环成链。具体方法如下:
假设有一个环 \(A_1 \to B_1 \to C_1 \to A_1\)(字母表示发出者),且 \(A\) 的学术消息是 \(a\),当前接在 \(a\) 两侧的是 \(x \to a \to y\)(\(x\),\(y\)均为一条链或者没有)。
那么我们就可以把环接到链上,形成 (楼上形的环)\(x \to A_1 \to B_1 \to C_1 \to a \to y\) 或 (楼下形的环)\(x \to a \to B_1 \to C_1 \to A_1 \to y\),这两种方案显然合法且总贡献不变。
上面那个最小路径覆盖是用二分图做的,但是这样边数爆炸。
考虑优化建图,对人建出入两个虚点。u v louxia 的话 \(v\) 的出点连向这个消息的入点;u v loushang 的话这个消息的出点连向 \(v\) 的入点。
然后用残量网络先找出方案,接着用双向链表维护断环成链的过程,就好了。
然后是没有性质 C 的情况:
这个时候会出现 a b loushang 和 b a louxia。这个时候把这俩接起来一定不劣。于是可以合并成一个 \(a\) 进 \(b\) 出的学术消息。
写起来比较恶心,而且我又被卡常了/cf
来自题解的卡常技巧:把所有边类型反一反,输出倒序。
这说明了如何加边对 Dinic 的极大影响(
原来我10天才能补完 Day1/cf
2023/3/16
哈哈,我自己写出来啦,哈哈!
首先数都不超过 \(2000\),所以 \(n \leq 10^6\) 显然是假的,直接同一个数合并。
然后考虑把每个数映射到一个和它质因子集合有关的东西上。
因为 \(s_i \leq 2000\), 所以每个数最有一个质因子 \(\geq \sqrt{2000} ≈ 45\),而 \(45\) 以下的质数只有 \(14\) 个,因此我们完全可以把每个数写成一个 \(14\) 位的二进制数加一个数(那个 \(\ge 45\) 的数)。
把用上述表示方法表示出来后相等的数搞成一个等价类,那么我们就可以用 \(num[pr][bit]\) 来表示那个 \(14\) 位的二进制数等于 \(bit\) 且那个大于 \(45\) 的质数是 \(pr\) 的数的个数。
然后进行 \(dp\),求出 \(dp[i][j]\) 表示在 \(num[i]\) 中任选一些东西(可以为空),使得他们或起来等于 \(j\),这里的总复杂度是 \(O(2000*2^{14})\)。
然后对 \(dp\) 进行一个 FWT,处理出 \(fwt[i][j]=\sum_{k|j=j}dp[i][k]\),意义显然。
那么把所有 \(fwt\) 对应位置相乘,再逆变换回来(子集反演),然后枚举 \(bit\) 算贡献就行了。
但是在询问中,如果有大于 \(45\) 的质数(记为 \(pr\))出现,那么相当于在 \(num[pr]\) 中,我们不能不选。
而观察上面的 \(dp\) 和 \(fwt\) 我们发现,我们先让 \(dp[pr][0]=1\),因而 \(fwt\) 都会多这一个 \(1\)。
所以在出现 \(pr \geq 45\) 的时候,我们不再是直接乘上 \(fwt[pr][j]\),而是应该乘上 \(fwt[pr][j]-1\)。
考虑到有 \(\sum c_i \leq 18000\),我们先记录下所有的乘积,然后遇到必选的时候乘上逆元再乘 \(fwt[pr][j]-1\)。
然后做完了,卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡常就行。/cf
Bonus:
基本一样的处理方法,转成 \(num[pr][bit]\)(\(bit \leq 2^8, pr \leq \sqrt{500}≈22\))。
然后一样搞出 \(dp\) 数组,然后进行动态规划。
\(DP[i][j][k]\) 是前 \(i\) 个质数,一个人选完以后前 \(8\) 个质数状态是 \(j\),另一个人状态是 \(k\) 的方案数。
直接枚举当前质数选完以后前 \(8\) 个质数状态然后暴力转移,\(O(100 \times 2^{8 \times 3})\)(500内100个质数左右),跑不满,而且易优化成 \(O(100 \times 3^8 \times 2^8)\)。然后就好了。/hanx
2023/3/20:
啊对对对,啊对对对对对对对。
首先转成括号树,二操作允许交换同层相邻子树,进而可以交换同层任意子树。
一操作较复杂,见下图:

就是选两颗同层相邻子树 \(a,b\),把 \(b\) 和 \(b\) 的子树都接到 \(a\) 下。
目标是变成一根链。
那么首先有一个贪心就是从根往叶子搞,感性理解,首先 \(1\) 操作次数不变,那么我们要是每层操作自由度最大,那就从上到下每层都只剩一个节点。
接下来是喜闻乐见的分讨:
- \(x=0,y=0\)
输出 \(0\)。
- \(x=0,y=1\)
钦定一个留下来的点 \(u\) ,本层操作代价为 \(\sum_{v \neq u}val_v\)。
于是保留一个 \(val\) 最大的在本层,multiset 维护。
每层最优是全局最优的感性理解:\(val\) 越大显然尽量使对它的操作次数少,于是尽可能放在上层。
- \(x=1,y=1\)
钦定一个留下来的点 \(u\),设本层节点数为 \(S\)。
若 \(val_u\) 不是本层最小值,那么显然应该把本层其他的点先接到本层最小值上,再把最小值接到 \(u\) 上,操作代价为 \(\sum_{v} val_v+(S-2)\times val_{min}\)
否则 \(val_u\) 是本层最小值,直接全接上去,代价为 \(\sum_{v} val_v+(S-2)\times val_{min}\)。
两种情况代价相等,同上一种情况,丢下 \(val\) 最大的在本层,仍然是 multiset。
- \(x=1,y=0\)
/tuu
上面才32pts,黑的难度全是这个撑的是吧/tuu。
钦定一个留下来的点 \(u\),设本层节点数为 \(S\)。
有一个显然的东西就是不管 \(u\) 取什么,每一层的 \(S\) 固定。
同上一种情况分析得出本层代价为 \(val_u +(S-2)\times val_{min}\)。
但是这里不能丢最大值跑路了,要整体考虑。
考虑前 \(n-1\) 层,被保留的点都会对答案有贡献,因此我们想要把最大值往下扔。
但是每层都有 \((S-2)\times val_{min}\) 的贡献,因此我们想把最小值也往下扔。
因此我们得到了一个关键想法:最小值和最大值都下放。
那么当本层 \(S=1\) 时没得选, \(S \geq 3\)时取一个中间值(比如什么次大值)留下就行了。
于是来到了最恶心的 \(S=2\)。
首先有一个结论,第 \(i\) 层的 \(S_i\) 一定是一个先单调不降,再逐个减少 \(1\) 的序列。证明比较显然:因为有一段前缀(原树深度)会使 \(S\) 减 \(1\) 然后加上一个 \(\geq 1\) 的数,后半段就是每次减 \(1\)。
写出来就是 \([1,1\dots1,2,2 \dots,2,\geq 3,\geq 3,\dots,3,2,1]\)。
由此,\(S=2\) 的是一段连续区间(最后一个 \(2\) 可以直接取 \(\min\) 做掉)。
可以发现,对于这段区间,只有一个数能够被送到 \(S \geq 3\) 的部分,而我们想要的是把最小值和最大值送下去,但是现在只能送一个。
那就好办了,直接算两遍,一遍送最小值,一遍送最大值,然后万事大吉。
码码码。。。
诶其实不算难写,而且我没有卡常!
(其实我并不会正确性的严谨证明。。感性理解,有证明或证伪都踹我一脚)
不会。看了题解。更不会了。写这个东西还是太困难了。
2023
完全签到题。
先把经过起点的区间 \([l,r]\) 裂成 \([l,st],[st,r]\) 两个,然后向左向右的分开做,每个方向都做一个类似并查集的东西。如果当前区间可以从起点到达,就把这个区间的终点(向左的是左端点,向右的右端点)加入答案。
细节就是把起点排除掉,然后那个并查集可以用区间并集搞。
我和贪心势不两立!
删除操作很恶心,先不管。我们先来看不带删除怎么做。
定义一个员工为 \((u,x)\) 表示初始部门是 \(u\),能力值是 \(x\)。
考虑对每个点 \(u\) 维护一个员工集合 \(S_u\),满足 \(\forall u\),\(S_u\)是初始部门是 \(u\) 的员工集合的子集。并且,将所有员工 \((U,x)\) 与其初始部门 \(U\) 的子树中所有的点连边,形成一张员工到点的二分图,满足该二分图存在员工的完美匹配。
这样就满足了存在一种题目中的分配(下放)方式,使得所有点上的员工数 \(\leq 1\)。
相当于不考虑一个方案中没有贡献的点,而根据最优性,题目的一个最优方案一定能和一组 \(S_u\) 一一对应。
设 \(size_u\) 是 \(u\) 的子树大小。
根据 Hall 定理,一个方案满足条件的充要条件是 \(\forall u,\sum_{v\in u\text{的子树}}|S_v|\leq size_u\),即子树内保留的员工个数不超过子树大小。
证明感性理解,大概是每个员工子集都拆成不相交子树,然后在一个子树内限制尽量紧,于是把子树内所有的员工算上也要满足。具体不证了(要的话评论加一下)。
记 \(left_u=size_u-\sum_{v\in u\text{的子树}}|S_v|\),即 \(u\) 的子树内还能放多少个员工。于是方案合法等价于 \(\forall u,left_u\geq 0\)。
考虑加入一个员工 \((u,x)\) 的影响。
如果直接加入这个员工合法,那么由于加入它会使 \(u\) 及其祖先子树中的空位都减少 1,所以要满足 \(u\) 及其祖先的 \(left\) 均不为 0。此时直接在 \(u\) 加入这个员工是合法的。那么就果断加入。
但是如果 \(u\) 及其祖先的 \(left\) 存在一个点为 0 呢?
那我们如果要加入这个员工,必定要踢掉一个。我们找到 \(u\) 及其祖先中,深度最深且 \(left=0\) 的点,记为 \(v\)。由上面的充要条件得,这个时候必须在 \(v\) 的子树内踢掉一个。
于是我们查询 \(v\) 的子树内保留的员工的最小值。若用现在这个员工替换他更优,那么我们就踢掉一个最小值,并加入当前员工 \((u,x)\)。
至此,不带删的东西做完了。
至于具体实现,我们树剖维护 \(left\),操作有链上 \(\pm 1\) 和查询链上最小值(及其最深的位置);而对于员工集合 \(S_u\),我们给每个节点开一个 multiset,记录员工的能力值集合。即 \(w_u\) 为 \(u\) 的 multiset 中的最小值(就是员工最小能力值),查询子树内员工最小值即为查询区间内 \(w\) 的最小值,同样可以树剖。而加入或踢掉员工都可以转化为在 multiset 上加数或删数,此时单个点的 \(w\) 可能会变化,那么直接在线段树上修改即可。
现复杂度 \(O(n\log^2n)\)。
好好好,带删怎么办?
离线后发现每个员工的存在时间都是一段区间,果断时间轴上分治,就可以将删除改为撤销。同时我们在树剖上的操作正好都是可撤销的(加/减和加入/删除),因此完美适配。
至此,我们在 \(O(n\log^3n)\) 的复杂度解决了这个问题!
Todo:

浙公网安备 33010602011771号