垂死挣扎

大概是退役前最后的挣扎了,不过颓了太久估计挣扎了也没啥用;

BZOJ4738汽水

平均值的话我们就二分一下,对于一个需要判断的\(mid\),我们需要找到一条路径平均值在\([K-mid,K+mid]\)之间;分两种情况讨论一下,如果存在一条路径的满足\(K\leq \frac{\sum w}{len}\leq K+mid\),即\(\sum (w-K)\geq 0\)\(\sum mid-(w-K)\geq 0\);考虑点分治,我们将边权\(w_i\)搞成\(w_i-K\),处理出每个点到分治中心的边权和\(p_i\)和边的数量\(d_i\),即我们需要找到不同子树中的两个点\(i,j\)满足\(p_i+p_j\geq 0,mid\times d_i-p_i+mid\times d_j-p_j\geq 0\);按照\(p_i\)从小到大排序,扫大于\(0\)\(p_i\)之后把小于\(0\)的加进去,同时维护\(mid\times d_i-p_i\)的最大值,由于需要来自不同子树,所以需要维护最大值和次大值;另一种情况类似。

复杂度是\(O(n\log n(\log n+\log w))\)代码

HZOI省选模拟65A 容器

比较经典的套路了,从左向右考虑这个序列,设\(dp_{i,j,k}\)表示当前处理了前\(i\)个点,有\(j\)个左端点确定右端点没定的区间,还有\(k\)个左右端点都没确定的区间的方案数;转移的时候枚举一下有\(x\)个区间是以\(i+1\)为左端点,这边是一个组合数\(\binom{k}{x}\);之后再枚举一下有\(y\)个区间以\(i+1\)为右端点,还是一个组合数\(\binom{x+j}{y}\),乘上这两个组合数转移就好了。

复杂度是\(O(nK^4)\)代码

HZOI省选模拟65B 果树

由于每一种颜色的点数不会超过\(20\)个,所以我们将一对颜色相同点\(i,j\)视为一条限制"一条合法路径上不能同时出现\(i,j\)两个点",这样限制的个数大概是\(20n\)级别;如果\(i,j\)不是祖先-后代关系,那么一条合法路径的两个端点不可能分别来自于子树\(i\)和子树\(j\);用dfs序刻画一下这个条件就是如果\(x\in [l_i,r_i],y\in [l_j,r_j]\),那么\((x,y)\)不是一条合法路径,其中\([l_i,r_i]\)是子树\(i\)的dfs序区间;祖先-后代关系的话类似,也可以写成类似的限制。于是我们就得到了\(20n\)个这样的限制,即二维平面上一个矩形内的点不是合法路径,我们要求的就是有多少点没有被矩形覆盖,用线段树做一个矩形面积并即可。

复杂度是\(O(20n\log n)\)代码

HZOI省选模拟65C 流浪

注意到能到达的点在一个曼哈顿距离意义下的半径为\(T\)的圆内,所以能到达的点有\(T^2\)个;直接对每条路径统计答案比较难算,考虑对于这\(T^2\)个点分别求有多少条路径经过了这个点\(k\)次,最后加起来即可;

对于每个点\((x,y)\),求一个\(f_{i}\)表示从\((0,0)\)出发走了\(i\)步不经过障碍以及\((x,y)\),最后停在了\((x,y)\)的路径数;一个\(g_{i}\)表示从\((x,y)\)出发不经过\((x,y)\)走了\(i\)步最户停在了\((x,y)\)的路径数;一个\(dp_{i,j}\)表示从\((x,y)\)走了\(i\)步回到\((x,y)\)且经过了\(j\)\((x,y)\)的路径数,转移大概是\(dp_{i,j}=\sum_{k}dp_{i-k,j-1}\times g_k\)\(d_i\)表示从\((x,y)\)出发走了\(i\)步不经过\((x,y)\)的方案数。我们对\(d\)\(dp\)做一个卷积,得到\(h_{i}\)表示从\((x,y)\)走了\(i\)步,经过\((x,y)\)不少于\(k\)次的路径数;有了\(p\)再和\(f\)做一个卷积即可。

上面所有数组都能在不超过\(O(T^3)\)的时间内求出,对\(T^2\)个点均求一遍,复杂度是\(O(T^5)\)

HZOI省选模拟63C 营养餐

转化一下题意,设\(c_i=a_i-\sum_{j\in son(i)}a_j\times b_j\),轮流操作,每次选择一个大于\(0\)\(c_i\),使得\(c_i=c_i-x\)\(c_{fa_i}=c_{fa_i}+x\times b_i\),不能操作的人输。不难发现当所有\(b_i=0\)时,就是变成了令一个\(c_i\)减去一个\(x\),不能操作的人输,这就是一个普通的Nim游戏,求一下\(c_i\)的异或和即可;对于更一般的情况,不难发现这本质是一个阶梯Nim;当\(i\)深度为偶数时,操作\(c_i\)后下一个操作的人总可以把移入\(c_{fa_i}\)的哪一部分移动到上面去,所以求一下深度为奇数的点的\(c_i\)的异或和即可;对于\(b_i=0\)的点,操作它时并不能使得其父亲的权值增加,所以我们可以将这类点视为一种特殊的根,即规定该点的深度为\(1\)即可。

复杂度是\(O(Tn)\)代码

HZOI省选模拟69C 排列问题

对于\(i\)颜色的小球,如果我们将其分成\(j\)段,则贡献至少为\(a_i-j\);对于每种颜色搞一个\(\rm EGF\),即\(F_i(x)=\sum_{j=1}^{a_i}\binom{a_i-1}{j-1}\frac{x^j}{j!}\),即枚举每种颜色分成了多少段之后再排列起来,由于同种颜色的两段还有可能相邻,所以至少\(m-\sum j\)对小球是颜色相同的,还需要容斥一波;于是分治NTT求出\(\prod_{i=1}^nF_i(x)\)进行二项式反演即可。

复杂度\(O(m\log m\log n)\)代码

HZOI省选模拟74A 签到

先上结论:从这个\(n\times m\)的矩阵中选出一些点,如果点的个数的奇偶性和\(n+m-1\)的奇偶性相同,那么这些点的异或值可以作为答案。

考虑证明,对于这类问题一个经典的做法是处理出所有简单环的异或值,之后搞一条从起点到终点的路径,把这些环拼到这条路径上去;但这个做法是权值在边上的情况,当权值在点上时我们发现环上和路径上共两个点被经过了两次,也就是这两个点的权值被抵消了;又因为这是一张网格图,不存在奇环,于是我们无论经过多少个环都不会改变经过的点的个数的奇偶性。于是经过的点的个数的奇偶性和\(n+m-1\)的奇偶性相同。

现在的问题就是从\(n\times m\)个数里选奇数/偶数个,使得其异或值最大;我们令每一个点或上\(2^{31}\)之后插入线性基,当第\(31\)\(1\)的话则说明选了奇数个,否则就是选了偶数个;于是我们从第\(31\)位或第\(30\)为开始做线性基求最大值即可。复杂度\(O(nm\log w)\)

HZOI省选模拟74B 树

分块;我们将序列分成\(\sqrt{n}\)个块,对于每一个块我们跑一遍spfa,对于每个点处理出到块内点的最短路;查询的时候扫一遍整块,零散块直接用lca算距离即可;

lca可以用\(O(n\log n)-O(1)\)的方法,由于在树上跑spfa的实际运行次数大概是\(O(n)\)级别,所以复杂度为\(O((n+m)\sqrt{n})\)代码

NOI Online#2 C

直接做不好做,考虑容斥,求一下至少出现\(i\)个非平局回合的方案数;非平局就代表这一次选的两个点存在祖先-后代关系,于是可以转化成一个匹配问题:一棵树,祖先与后代可以匹配,两个点集各\(m\)个点,求至少有\(i\)组匹配的方案数。之后二项式反演一波即可。

树上的匹配大概是需要一个背包状物,设\(dp_{i,j}\)表示子树\(i\)中有\(j\)\(0\)点已匹配的方案数。当\(i\)点为\(0\)的时,可以考虑把点\(i\)和子树内的一个未被匹配的\(1\)点匹配上,由于我们知道了有\(j\)\(0\)点已经匹配了,所以未被匹配的\(1\)点也是已知的;当\(i\)点为\(1\)时,我们考虑匹配子树内的一个未被匹配的\(0\)点,这个数量也是已知的。子树间的合并直接暴力卷积即可。

复杂度\(O(n^2)\)代码

HZOI省选模拟74B 遇见

比较有趣的一个题。考虑一下我们如何刻画区间\([l,r]\)内所有数都出现了奇数次这样一个条件,发现比较困难。考虑一个差不多的问题,如何快速判断一个区间\([l,r]\)内所有数都出现了偶数次。这其实是一个经典随机化问题,我们给每种数随机一个权值,做一个异或前缀和,如果满足\(pre_r\bigoplus pre_{l-1}=0\),那么就说明区间内的数两两抵消,即都出现偶数次,当随机范围在\(2^{64}\)之内时,判断错误的概率只有\(2^{-64}\)

于是我们用上面那个随机化的思想来做这个题,设\(w_{l,r}\)表示区间\([l,r]\)内所有出现过的数的权值异或和,当\(pre_{r}\bigoplus pre_{l-1}=w_{l,r}\)时,我们就可以认为这个区间内所有的数都出现了奇数次。考虑枚举左端点\(l\),我们只需要计算有多少个\(r\geq l\)满足\(pre_{r}\bigoplus w_{l,r}=pre_{l-1}\)即可。

考虑从\(w_{l,r}\)\(w_{l+1,r}\)有什么变化。如果\(a_l\)\([l,r]\)内只出现了一次,那么\(w_{l+1,r}\)内就少了\(a_l\)的异或值;否则就不变,我们设\(lst_l\)表示\(l\)后第一个等于\(a_l\)数的位置,我们只需要令\(r\in [l+1,lst_l-1]\)内的\(w_{l,r}\)异或上\(a_l\)的权值就可以把它们变成\(w_{l+1,r}\)了。

我们现在需要一个数据结构,支持区间异或一个数,查询一个区间内等于某个值的有多少个,显然分块+trie就可以了,复杂度是\(O((n+m)\sqrt{n}\log w)\)代码。其实NOI Online#2的B题也是差不多的套路,会做这个题那道题就很简单了。

ZR五一省选集训day1 A

\(P(y)=\sum_{i=0}^k p_iy^i\),设\(G(y)=P^n(y)\),经过一番奥秘重重的推导,期望其实是\(x-\sum_{i=0}^xg_i(x-i)\);即求出\(G(y)\)的前\(x\)项系数就可以直接算答案了;

考虑对\(P^{n+1}(y)\)求导,我们可以把它看成一个复合函数,用链式法则来求导;也可以把它看成\(P(y)\times G(y)\),于是分别有两种不同的结果:

\[(P^{n+1}(y))'=(n+1)G(y)P'(y) \]

\[(P^{n+1}(y))'=P'(y)G(y)+G'(y)P(y) \]

联立两个式子可得

\[nG(y)P'(y)=G'(y)P(y) \]

显然这两个多项式对位相等,于是我们可以诸位确定;\(P(y),nP'(y)\)的次数都不超过\(k\),所以可以用\(O(k)\)的时间得到一位的值。

复杂度\(O(xk)\)代码

ZR五一省选集训day1 B

不妨求所有位置都是\(0\)的概率,显然与所有位置都是\(1\)是等价的,于是求出这个概率后乘\(2\)即可。

设第\(n\)\(0\)出现的位置是\(A\),第\(n\)\(1\)出现的位置是\(B\),分情况讨论一下。

\(A<B\)时,我们枚举\(A=i\),由于大于\(A\)的位置都是\(1\),所以要满足\(\max a\leq i\)。当\(i>\max a\)时,概率为\(\frac{\binom{i-1-k}{n-1-k}}{2^i}\),即前\(i-1\)个位置中有\(n-1\)\(0\),且有\(k\)\(0\)的位置是已经确定了的,于是就从剩下的\(i-1-k\)个位置里再选\(n-1-k\)个当\(0\);当\(i=\max a\)时,概率为\(\frac{\binom{i-k}{n-k}}{2^i}\),这个直接\(O(1)\)算就好了。

\(A>B\)时,枚举\(B=i\),概率为\(\frac{\binom{i-1-\sum[a_j<i]}{n-1}}{2^i}\),即前\(i-1\)个位置中有\(n-1\)个是\(1\),但有\(\sum[a_j<i]\)个位置被确定是\(0\),于是就从剩下的\(i-1-\sum[a_j<i]\)里选\(n-1\)个位置当\(1\)即可。

根据上面的分析可以发现,要求的式子都形如\(\sum_{i=l}^r\frac{\binom{i-1-x}{n-1-y}}{2^i}\),转化一下大概是\(\frac{1}{2^{x+1}}\sum_{i=l-1-x}^{r-1-x}\frac{\binom{i}{n-1-y}}{2^i}\);如果我们能对每一种\(y\)求一个前缀和,那么就能快速求得这个式子,但是\(y\)能达到\(n\)级别,所以看起来比较棘手。但是不难注意到这里的\(y\)就是上面的\(k\),而\(\sum k\leq n\),于是本质不同的\(k\)只有\(O(\sqrt{n})\)种,于是对于每一种出现的\(y\)都能求一个前缀和,就能快速回答这些式子的值了。

复杂度是\(O((n+m)\sqrt{n})\)代码

ZR五一省选集训day2 A

考虑两个点\(a_1,a_n\)在什么时候会联通,即存在一条路径\(<a_1,a_2\dots ,a_n>\)满足\(\forall i<n\)都有\(a_i\bigoplus a_{i+1}\in S\)。我们注意到\(\bigoplus \sum_{i=1}^{n-1}a_i\bigoplus a_{i+1}=a_1\bigoplus a_n\),即这条路径中所有边的边权异或和就是两个端点的异或和。由于所有边的边权都是属于集合\(S\),那么\(a_1\bigoplus a_n\)就是集合\(S\)的一个子集的异或和。于是我们可以得出,如果\(u,v\)两点联通,那么\(u\bigoplus v\)一定能被\(S\)的线性基表示出来

一个大小为\(x\)的线性基能表示出\(2^x\)种数,于是对于任意一个点来说,和其在同一个联通块的点有\(2^x\)个,即每一个联通块的大小都是\(2^x\),那么联通块的个数就是\(2^{n-x}\)个。于是需要维护一个支持插入并且能够删除元素的线性基。

由于可以离线,所以对于每个元素求出其删除时间,插入线性基的时候优先保留删除时间靠后的元素,这样的时间复杂度是\(O(nq)\)代码

ZR五一省选集训day2 B

考虑当\(m=\binom{n}{2}\)时的做法,这个时候任意两个点的权值都不相等,于是所每一种方案都有\(n\)种权值,求一下方案数即可;按照\(R_i\)从小到大排序,之后按顺序确定每一个点的取值,第\(i\)个点不能和其前面的\(i-1\)个点一样,于是有\(R_i+1_(i-1)\)个选择,于是方案数就是\(\prod_{i=1}^n(R_i-i+2)\)

对于更一般的情况,我们沿用上面的方法,先将所有点重编号使得\(R_i\)是不降的;搞一个\(dp_{i,S}\)表示当前集合\(S\)已经确定了\(i\)种权值的方案数,先找到一个最小的\(x\)满足\(x\notin S\),之后再枚举一个集合\(T\)满足\(x\in T,T\cap S=\varnothing\),令集合\(T\)中的点取值都相等。由于\(R_i\)不降,所以\(x\)\(T\)中取值范围最小的点,于是集合\(T\)的取值范围就是\([0,R_x]\),转移的话乘上\(R_x-i+2\)转移即可。

由于需要枚举子集,所以复杂度是\(O(n3^{n-1})\)代码

ZR五一省选集训day2 C

不难发现一个集合的\(\gcd\)不会超过\(w\),于是考虑对于每一个质数次幂计算贡献,设\(f(p^k)\)表示有多少个集合的\(\gcd\)\(p^k\)的倍数,那么答案就是

\[\prod_{p\in Prime}\prod_{k>0}(p^k)^{f(p^k)-f(p^{k+1})} \]

\[\prod_{p\in Prime} p^{\sum_{k>0}k(f(p^k)-f(p^{k+1}))} \]

\[\prod_{p\in Prime} p^{\sum_{k>0}f(p^k)} \]

\(g(p^k)\)表示有多个数是\(p^k\)的倍数,显然有\(f(p^k)=2^{g(p^k)}-1\),由于询问是一堆区间,所以考虑使用莫队。

加入一个数\(x\)时,如果\(p^k|x\),那么\(g'(p^k)=g(p^k)+1,ans'=ans\times p^{2^{g(p^k)}}\);同理删除一个数\(x\)时,如果\(p^k|x\),那么\(g'(p^k)=g(p^k)-1,ans'=\frac{ans}{p^{2^{g(p^k)}}}\)

显然一个数的质数次幂和不会超过\(\log w\),所以直接使用上面的做法复杂度是\(O((n+m)\sqrt{n}\log w)\),并不是非常优秀。

考虑把不超过\(\sqrt{w}\)的质数称为小质数,大于\(\sqrt{w}\)的称为大质数;对于这两种质数分别使用不同的算法。

对于大质数,我们直接使用上面的莫队,由于一个数最多有一个质数次幂大于\(\sqrt{w}\),于是加入/删除的复杂度都是\(O(1)\),这部分的复杂度就是\(O(n\sqrt{m})\)

对于小质数,我们处理一个前缀和\(pre(i,p^k)\)表示前\(i\)个数种有多少个数是\(p^k\)的倍数,有了这个前缀和就能快速计算\(g(p^k)\)\(f(p^k)\)了,这部分的复杂度是\(O((n+m)\sum_{p\in Prime,p\leq \sqrt{w}}\log_p w)\),通过一番奥妙重重的推导,这边的复杂度是\(O((n+m)\frac{\sqrt{w}}{\log w})\)

CF407E

显然只有模\(d\)意义下相等的数才有可能构成等差数列,于是按照模\(d\)意义下的值分段,对每一段单独处理。设\(v_i=\lfloor \frac{a_i}{d}\rfloor\),那么一个区间\([l,r]\)构成等差数列的冲要条件是,\(\max\{v_l\dots v_r\}-\min\{v_l\dots v_r\}-(r-l+1)\leq k\),即\(\max\{v_l\dots v_r\}-\min\{v_l\dots v_r\}+l\leq k+r\)。考虑从小到大枚举右端点\(r\),那么那个\(\max-\min+l\)我们可以使用单调栈+线段树维护,之后我们要在线段树上找到一个最靠左的\(l\)满足\(\max-\min+l\leq k+r\),于是直接在线段树上二分即可。

需要特殊处理\(d=0\)和相同数出现多次的情况;时间复杂度是\(O(n\log n)\)代码

ZR五一省选集训Day5 B

\(p_{i,j}\)表示经过了\(m\)次操作,\(j\)位置上的数经过交换到了\(i\)位置上的概率,有了这个数组我们就能快速计算答案了;不难发现我们其实并不需要知道\(i\)是多少,我们只关心\(i\%d\)是多少,甚至我们也不关心\(j\)是多少,只需要知道\(j\)上的数字和颜色即可,而颜色只有\(d\)种。这样\(p\)的两维就被我们限制在了\([0,d)\),于是使用矩阵乘法可以在\(O(d^3\log n)\)的时间内求出\(p\),又因为这个转移矩阵是一个循环矩阵,求出第一行后就可以推出整个矩阵,所以\(O(d^2\log m)\)即可求出转移矩阵;需要对\(\frac{n}{d}\)个前缀都求一次,所以时间复杂度是\(O(dn\log m)\)

这个时间复杂度并不能通过。但是我们发现当交换次数非常多时,\(j\)被交换到每一个位置的概率大致相等,即\(\forall i,j\in [0,d),p_{i,j}\approx \frac{1}{d}\),这道题的精度要求并不高,于是直接这样近似认为即可。

posted @ 2020-04-11 13:52  asuldb  阅读(118)  评论(1编辑  收藏  举报