二轮前水题记
5.4
洛谷P4607 [SDOI2018]反回文串
神仙反演Orzzzzzzzzzz
首先一个串的本质不同的轮换个数是不重叠最小循环节的长度
如果最小循环节的长度(d)是偶数,此时一个回文串的(d)种不同的轮换字符串当中恰好有两个回文串(本身一个,把前(frac{d}{2})个字符拼到后面一个)
否则(d)是奇数的话一定会有(d)个本质不同的字符串
首先考虑字符集为(k)的情况下回文串的数量(g(n))
显然(g(n) = k^{lfloorfrac{n+1}{2} floor})(固定一半)
那么设
设(f(i))表示最小循环节为(i)的字符串数量,显然有
(Ans(n) = sum_{d|n} h(d) f(d))
(f(d))很难直接求,但是我们可以枚举循环节得到一个等式
反演一下
带入原来的公式
我们尝试枚举(g)
把(d)拆为(d = d' * K),我们去枚举新的(d')
之前我们发现(h)函数有比较好的性质,这里似乎可以直接把(d)提出来。分析一下不难发现,只有当(d)是偶数且(k)是奇数是不能直接提。因为一个奇数不会有偶数因子,那么(frac{n}{k})一定是偶数
此时把式子中的(k)提出来,考虑一下(ksum_{d|frac{n}{k}} h(d)mu(d))的值,打一下表可以发现值总是(0),因为(2)这个因子使得(mu)为(pm 1)的项消掉了
那么在计算这时候直接把这种情况判掉就可以
原式变为
然后直接对(n)进行Pollard-Rho分解,分解的同时可以求出后面的值,拿个map存一下。
然后dfs枚举约数直接算就行了
复杂度玄学,但是出题人把(n)出到(10^{18})也只能这么干。。
5.3
洛谷P4606 [SDOI2018]战略游戏
首先建出圆方树,那么答案为包含所有询问点的最小联通块大小 减去关键点个数
最小联通块大小可以转化为边的贡献最后特判LCA,将所有点按dfs序排序后算出相邻两点的dis,最后/2即可
复杂度(O(n log n))
5.2
洛谷P4620 [SDOI2018]荣誉称号
每个位置(x)向(frac{x}{2})连边最终会得到一棵完全二叉树
题目转化为:给出一个有点权的树,对于每个点可以花费(b_i)的代价使点权增加(1),问使得所有长度为(k + 1)的链的点权和(\% M)均为(0)的最小花费
首先考虑序列的情况,稍加归纳后不难得到(a_i equiv a_{i + K + 1} pmod M)
放到树上话那么最终一个点的权值一定和它的(K+1)级祖先相同,因此对于前(2^{k})个点,我们(O(nm))预处理出(w[x][y])表示(x)的点为(y)时,所有能被它限制的点的代价
现在只需要考虑前(2^{k+1}-1)个点,首先把标号(< 2^k)的叶子节点删掉,对于剩下的点的限制条件变为所有叶子节点到根的路径和(\% M =0)。那么设(f[i][j])表示以(i)为根的子树,到所有叶子节点的权值(\%M = j)的最小代价,转移的时候暴力枚举该点的取值。
复杂度(O(nm + 2^k m^2))可以拿到70分
考虑(w)的预处理,std在这里用了一个等差数列,实际上不用这么麻烦,因为(a[i])取值只有(200),直接对值域暴力就行
复杂度(O(n + 2^k m^2))
4.26
BZOJ4145: [AMPPZ2014]The Prices
f[sta][i]表示买完sta中集合中的物品,当前在i号城市的最小代价
转移的时候枚举一下最后买的物品以及从哪儿买
前缀和优化一下
复杂度O(n2^mm)
cf 1129 E. Legendary Tree
每次可以给定两个不相交且非空的点集以及一个常数({S}, {T}, p),系统会返回(u∈S, v∈T)且(u, v)经过p的点的对数。
需要在11111次操作后还原出树的形态
n <= 500
首先转化为有根树,假设1是根。根据题目描述我们实际上得到了几个操作
1.询问点集S中有多少在p的子树内 - ({S}, {1}, p)即可
2.询问某个点p的子树大小 - {{2, 3, 4, 5}, {1}, p}
接下来考虑怎么还原出一棵树,显然我们只要维护出父子关系就行了
首先询问出所有点的siz,从小到大排序,那么此时每个点的孩子一定在它左边。接下来动态的从做往右扫,实时维护一下没有找到父亲的所有节点。
然后直接在点集中二分就行了。
UOJ #311. 【UNR #2】积劳成疾
每个长度为k的区间都是独立的,所以我们直接对着最大值dp
f[i][j]表示长度为i的序列,最大值为<=j时 的所有答案,也就是对整体进行dp
转移的时候只需要考虑第一个j在哪儿,其余的可以通过f[i][j - 1]转移
icpc 2018 焦作 I
给出数轴上(n)个点,要求选出(k)个点,最大化两两的距离,对于所有的(k=1, 2, 3, dots n)都要输出答案
有点小神仙,推出来感觉还是很有成就感的qwq
手玩一下不难得到最优策略:
偶数往两边放,同时维护任意对称点之间的距离
奇数往没放过的点放,往哪里放的贡献都是一样的,是上一次偶数放的两个点之间的距离
CometOJ#2 C
枚举独立集的大小是多少。那么最终答案是$sum_{i=1}^n C_{n}^i * (frac{x}{y})^{frac{i(i-1)}{2}}
4.29
cf618 F. Double Knapsack
一个很强的限制条件是(a_i, b_i <= N)
我们首先求出两个序列的前缀和,记为(sa, sb)
同时对于所有的(i),找到最大的(0 <= sa[i] - sb[j] < N)的最大的(j),记新的数组为(d_i)
显然(d_i)的取值最多有(n)个,但是由于是前缀和,因此(sa[0])也会有贡献(这个回路有点奇葩,看到下面就理解了)
也就是说(n)个位置,有(n+1)个取值,一定有一对是相同的
换句话说一定可以找到(sa_i - sb_{j} = sa_{i'} - sb_{j'}),移一下项有(sa_i - sa_{i'} =sb_{j} - sb_{j'})
因此我们求出(d)数组即可
loj#3083. 「GXOI / GZOI2019」与或和
单调栈入门题。
首先二进制拆分一下则我们只需要统计每一位的贡献。
第一问相当于求有多少矩形全为1
第二问相当于求有多少矩阵至少有一个1,相当于总数-全是0,取反之后相当于求多与少矩阵全为1,和第一问是一样的。
然后直接单调栈n^2
loj#2952. 「NOIP2018」赛道修建
傻逼贪心
首先二分一个答案
然后从从底向上合并,check的时候只需要判断是否能合成长度>=mid的链
4.30
洛谷P4559 [JSOI2018]列队
主席树板子题
每次需要在主席树上二分一个mid,满足(mid - K + 1 = num[1 - mid]),然后xjb搞一搞
mmp写的代码一开O2就RE。本机一点问题都没有,不调了。。
loj#6253. 「CodePlus 2017 11 月赛」Yazid 的新生舞会
这题淦了我一下午,,不过还好最后淦出来了qwq
考虑每个数的贡献,显然每个区间[l, r]最多被统计一次
设当前数为x, 那么[l, r]能产生贡献当且仅当(2sum_{l, r} > r - l + 1)
求个前缀和也就是(2s_r - r > 2s_{l - 1} + {l - 1})
然后相当于每次加公差为1的等差数列,线段树维护一下就好了