• 一句话题解2


    目录


    7026. 2021.03.26【2021省赛模拟】序列

    KD-tree板题。直接上就过了。时间(O(nsqrt n))

    也可以莫队,由于修改不满足交换律,所以需要额外用个线段树来维护。时间(O(nsqrt nlg n))。跑得比kd-tree快?


    7027. 2021.03.26【2021省赛模拟】a

    暴力做法:枚举(xmod m=r)。然后相当于有些位置已经被固定选什么,大概要求(prod(1+x^{2^i})mod(x^m-1))的某一项。时间(O(nm^2))

    (2^kmod m)相同的分在一起,排个序,那么相当于求序列上的三段的卷积,再卷起来。实际上两个分界点是关于中点对称的,所以可以维护中间那段,前后两段卷积,得到两个多项式之后可以(O(m))查单点。时间(O(m^2))

    zys的高级做法:把第(k)为0变1,和1变0视作一个“操作”,将其丢入数组中,排序。排序之后分成对称的两边。考虑原先的问题,现在枚举某操作(i),表示把(i)改变之后这个数会被(m)整除。为了不算重,它应该是第一个操作。所以前面和它数值一样的操作都被固定了。又由于左右对称,只需要前面一段和中点前面一段卷起来即可。

    (m)为偶数时,设(m=2^kq)。有两种情况:最小的(k)位中只有一个(1),此时(k)位后面的整数截出来被(m)整除;这(k)位中没有(1),把(q)替换(m)(n-k)替换(n),再做奇数的方法。


    7028. 2021.03.26【2021省赛模拟】旅行

    明明做过又不会做

    枚举第(k)大边权(lim),把所有边的边权改为(max(x-lim,0)),最终答案加上(k*lim)

    称长度大于等于(lim)的为大边。如果走了不足(k)条大边的情况,相当于要用(lim)将其补到有(k)条,因为此时前(k)大小于(lim),这一定会比实际情况劣。

    于是如果真实最短路第(k)大为(lim),确实可以算到;否则,也不可能占便宜。


    7032. 2021.03.28【2021省赛模拟】制作美食

    每个(x)连向([1,a_x])(b_y)最大的(y)(如果(b_yge x),否则这个点孤立)。只连这些边,然后计算连通块个数即可。

    正确性:不妨把连出去的边看成有向边。发现大于等于(2)的连通块(只考虑了所有边的时候)中,一定存在两个点(x,y)满足((x,y),(y,x))都连边。我们这样建图的时候,手玩一下发现它不会形成除了(x,y)之外的环。于是如果去掉孤立点,(x,y)互相连接的个数就等于连通块数,且这个(x,y)所在的连通块的点集和真实的点集一样。


    7033. 2021.03.28【2021省赛模拟】超命运树

    判定条件:(f(S)=1),当且仅当(S)排序后相邻的数(S_i,S_{i+1})满足(min_{i=S_i}^{S_{i+1}}P_i)不重复。

    考虑(len(S)=len(T))时,(S)的条件。经过一堆分类讨论可以得出。然后设(dp_{i,0/1/2})表示(T)中最后一个数在(i)(i)不作为(min),作为(min),将要作为(min)。再经过若干分类讨论得到(O(n^2))做法。然后显然可以用笛卡尔树将其优化成(O(n))

    好像如果一开始就建出笛卡尔树,可以更加清楚地看见它的判定条件(在笛卡尔树上的意义)。


    7034. 2021.03.28【2021省赛模拟】道路的眼泪

    显然先建出同构树。第一问直接算每个点作为LCA的贡献,第二问可以写个树形DP。第三问发现异或后的点集差分一下就是枚举的集合,一一对应,所以直接组合数计算。都可以做到(O(n))


    ARC116

    A:根据分解后(2)的次数判断。

    B:排序之后直接算。

    C:只考虑(A_{i} eq A_{i-1})怎么做,算出之后插空。枚举最后一个,设(f_{i,j})表示最后一个是(i),长度为(j)的方案数。

    D:相当于异或和加和等于(M)。相当于对每一位枚举(x_i,c_i),要求(sum c_i2^i+sum (2x_i+c_i)2^i)。令(t_i=x_i+c_i),枚举(t_i),要乘一些系数,然后变成了个背包问题。

    E:二分+贪心。贪心的时候记(f_i)表示子树中没有被覆盖的最远点到(i)的距离,(g_i)表示子树中最近的起始点到(i)的距离,贪心决策。---


    6085. 【GDOI2019模拟2019.3.26】要换换名字

    可以对每个字符串和它的子序列连边,然后跑二分图匹配。

    只需要连至多(n)条边,根据Hall定理。


    6086. 【GDOI2019模拟2019.3.26】动态半平面交

    显然把每个(p^k)先拆出来。只需要处理有效的,估计一下大概是(n+1000+)

    考虑维护个主席树,时间轴是dfn,下标是深度。(frac{query(out_i)}{query(in_i-1)})可以询问一个子树中,某深度区间的贡献。

    再用个支持合并的线段树,存每个(p^k)出现的最浅深度。线段树合并到叶子的时候,在主席树中把深度大的那个贡献删去。

    时间(O(nlg nlg V)),空间(O(nlg^2 n))。(粗略)

    (不过由于它可能会出一些(2^{23})之类的点,使得空间好像变成了(O(nlg nlg V))。如果把(p^k)(p)相同的放在一起,(p)不同的顺序排列,这样似乎就卡不掉了,因为对于一个节点它有的(p^k)比较多的时候,线段树节点的共用部分会很多,所以还是把空间算成(O(nlg^2 n))吧……)


    6087. 【GDOI2019模拟2019.3.26】获取名额(口胡)

    差个简单优化想出来了啊。

    如果(1-frac{a_i}{x})比较小,那么乘几次精度就乘没了。所以先暴力乘小于某个阈值的几个(1-frac{a_i}{x})

    对于其它的,考虑lnexp。展开(ln (1-frac{a_i}{x})),枚举若干项。于是就是维护(a_i)的多少次方和。加起来之后(exp)

    直接做精度误差极大。但如果一开始把(a_i)变成(frac{a_i}{max a}),那就变成了个小于(1)的数,就不会爆炸增长了。

    适当调阈值就可以AC了吧。时间大概(O(nlg^2 n))


    7035. 2021.03.30【2021省赛模拟】神奇纸牌

    每个数字有(2^4)种状态,用(2^{2^4})枚举每个状态是否出现过,然后组合数计算。

    也可以写出个DP,DP中记下连通性,压状态之后矩阵乘法。

    zys神仙做法:可以感受到答案是(sum a_i i^n)的,解方程算出系数即可。


    7036. 2021.03.30【2021省赛模拟】凌乱平衡树

    首先可以维护出不合并时候的深度和。直接维护(siz),然后对答案直接进行加减。

    考虑合并的时候的增量。提取出左树的右链和右树的左链,设各自子树大小为(A_i,B_i)(从下往上)。如果(A_nge B_m),答案加(B_m)并且(m)减一;否则答案加(A_n)并且(n)减一。

    每次修改的时候,只会对这个序列有(O(1))的修改。问题是怎么维护这个东西。

    为方便差分一下,设为(a,b)。于是(b_i)的贡献为(b_isum[A_jge B_i])(a_i)同理。维护个权值线段树,把(b_i)挂在(B_i)位置上,对于节点维护(a)(b)的和以及出现次数,和答案,合并的时候能够维护答案。

    (A_i)视作(2A_i)(B_i)视作(2B_i-1),就不用讨论它们相等的情况了。

    时间(O(nlg n))


    7037. 2021.03.30【2021省赛模拟】打扫笛卡尔

    大发挥失常:虚空调试+看错题意+已经推出正解还在推更复杂的东西。

    一条边被走的概率是(frac{1}{2}),所以一棵固定的树的答案是(sum (frac{1}{2})^{deg_x}(deg_x+1))

    (f_n)表示(sum (frac{1}{2})^{deg_x}(deg_x+1))的期望,(g_n)表示(sum (frac{1}{2})^{deg_x})的期望。列出来化简得到:

    [g_n=1+frac{1}{n}sum_{i=0}^{n-1} g_i\ f_n=g_n+frac{1}{n}sum_{i=0}^{n-1} f_i ]

    前缀和,有逆元的时候可以(O(n))做。(g)是调和级数,(G(x)=-frac{ln(1-x)}{1-x})(F(x))也可以推可是解错了微分方程。

    由于要求(n!f_n),多瞪两眼就可以得到不用逆元的做法。


    7038. 2021.04.01【2021省赛模拟】异或

    原题。异或最小值是排序后相邻异或值的最小值。所以排序之后DP,设(f_i)表示最后一个选(i)的方案。用个Trie辅助转移。


    7039. 2021.04.01【2021省赛模拟】计数

    原题。稍微推一下生成函数,最后推出个(frac{1}{1-(ax+bx^k)}[x^n])这样的东西,展开,可以在(O(frac{n}{k}))时间内搞出来,最后时间是(O(nln n))


    2021.04.01【2021省赛模拟】优化

    (f(x))表示(k=x)时的答案,(f(x))为凸函数。

    用个线段树来存一个区间内(f(x)),合并的时候可以闵科夫斯基和,时间(O(nlg n))

    询问的时候,外面套一层wqs二分,对于区间对应的节点,每个分别二分得到当前斜率下的最优解。时间(O(nlg^3 n))

    其实也可以整体二分。于是每个节点中二分的范围在分治的过程中会减小,对于一个节点,在每一层中,二分的范围之和都是这个它的长度。于是所有节点在所有层中的二分范围长度和是(O(nlg nlg V))。实际上不用二分,暴力扫,也就做到了(O(nlg nlg V))的时间。


    LOJ3101. 「JSOI2019」精准预测(口胡)

    设点((x,i))表示(i)时刻(x)的生死(生(0)(1)),于是有:(c_{x,i}=1 o c_{x,i+1}=1,c_{x,i}=0 o c_{x,i-1}=0)

    对于边((u,v,t,0)),有(c_{u,t}=1 o c_{v,t+1}=1,c_{u,t}=0 o c_{v,t}=1)

    把每个点的关键时间提取出来,一共(O(n))个点,two-sat建图。

    问题相当于:对于每个((x,T)=0),询问:它是否能到达((x,T)=1);如果不能,询问能到达多少个((y,T)=0)

    于是就是个bitset的事了。


    6149. 【GDOI2019Day1模拟2019.4.28】盗梦空间

    建虚树,求出起点到每个点的最小距离。在虚树的相邻两个点之间找到分界点,然后分别计算;另外还有一些子树,用set除去已经在虚树中的子树,然后计算即可。

    现在问题是:询问一条祖先后代链上,挂在这个链上的子树的信息。愚蠢的做法是直接树剖,这样要写线段树而且要根据轻重儿子分类讨论,时间(O(nlg^2 n))。但实际上也可以倍增,对于每个点记一下其兄弟的信息,时间(O(nlg n))


    6150. 【GDOI2019Day1模拟2019.4.28】爱乐之城

    这道题教导我们如何划分子问题,而不是将一些强行组合的式子从头展开到尾。

    (A(n)=sum_{i=1}^nsum_{j=1}^n[iperp j]mu(i)mu(j)=sum i^2phi(i))(B(n)=sum_{i=1}^nsum_{j=1}^nmu(ij)=sum_{d=1}^nmu(d)(sum_{d|i,ile n}mu(i))^2)

    (推导(A(n))的时候用到了(sum_{j}[iperp j]j=frac{phi(i)+[i=1]}{2})

    都可以(O(nln n))预处理。((B)要差分再前缀和)

    题目要求(sum_{T}B(gcd(T))prod A(a_i))。按照套路搞:

    [sum_{d}B(d)sum [gcd(T)=d]prod A(a_i)\ =sum_Tsum_{d}B(d)sum_{d|a_i}sum_{de|a_i}mu(e)prod A(a_i)\ =sum_Tsum_{p|a_i}(sum_{d|p}B(d)mu(frac{p}{d}))prod A(a_i) ]

    左半部分先预处理。现在可以把式子看成(sum C(p)G(p))。现在考虑维护(G(p))。当加入值(v)时,对于(v)的每个因数(u),于是(G(p)leftarrow G(p)(1+A(v))+A(v))。由于保证了每个值不重复,所以总时间(O(nln n))


    6151. 【GDOI2019Day1模拟2019.4.28】星际穿越

    容斥,钦定一些分界点合并,合并一次容斥系数是(-1)。于是列出生成函数(F(x)=sum_{ige 1}(-1)^{i-1}frac{x^{Ki}}{(Ki)!^r})。另外最后一段有些区别,设为(G(x))

    于是答案即(frac{G(x)}{1-F(x)}[x^n](n!)^r)。直接多项式求逆即可。


    3056. 「HNOI2019」多边形

    显然终止状态是所有点连向(n)。如果没有到达终止态,每次一定可以找到(a<b<c<n)组成个四边形,弦为((a,c)),然后把它换成((b,n))。所以操作次数是(n-3-([2,n-1]中和n直接相连的点数))

    把和与(n)相连的边拉出,然后分成子问题。这样可以得到一个树形结构。方案数是(prod_xfrac{(sz_x-1)!}{prod_{yin son(x)} sz_y!})。可以化简。

    考虑一次操作对于树是什么影响。画一下可以发现类似于旋转,大概来说,原本(x o A,x o B,y o x,y o C)变成(y o A,y o x,x o B,x o C)(sz)的变化是(O(1))的,如果建出树并且知道对应编号就可以求。

    一条边对应节点是,这个节点的状态中,这条边对着(n)。建树的时候需要快速查(l,r)连向的公共点。愚蠢的做法是用bitset,MLE;聪明的做法是直接用set(l)连出的最大点和(r)连出的最小点就是其公共点。记得建树递归的时候一些显然对后面没有用的边要删去。


    7041. 2021.04.03【2021省赛模拟】Alice 和 Bob 双在玩游戏

    如果图中只有一个棋子,容易得到谁胜谁负。

    有多个棋子的时候,由于棋子之间没有互相依赖,可以分开搞。预处理(f_i)表示如果有个从(i)出发的棋子,谁会胜,以及可以续多少条命。如果有棋子(f_i)的和大于(0),则A胜。

    然后就是个背包的事情。


    7042. 2021.04.03【2021省赛模拟】时代的眼泪·SP(口胡)

    考虑对一个块的整体修改,把块中的点暴力跳,跳过的标记,如果跳到了则删去这个点。于是一个块只会跳(O(n))次。

    于是可以搞出个(O(nsqrt n))的算法:对于每个点,维护一下它向上跳了多少格,于是可以(O(1))单点当前的位置。修改时,对于整块,块中没有删去的点暴力跳,对于散块,如果被删去了,记一下之前删去的时间,于是可以通过求k级祖先迅速跳到当前位置,并且重新加入。查询时,整块直接查,散块要查k级祖先。

    维护哪些点没有被删除可以用链表。加入直接在后面加。

    原题的做法:对于一棵树,每次把所有叶子节点删掉,如果删了(O(T))次,剩下的叶子结点个数不超过(O(frac{n}{T}))个(称这些点为关键点)。于是每个点前(O(T))步暴力跳。每个关键点维护个线段树,下标为序列位置,值为深度。修改时,枚举每个关键点,区间改,区间查最小值。时间(O(nsqrt {nlg n}))


    UOJ607. 【UR #20】跳蚤电话

    题目要求加点的过程中保持一棵虚树的形态。也就是说,设(rk_i)表示(i)出现的时间。有(max(rk_u,rk_v)ge rk_{LCA(u,v)})

    把一个点的所有子树中的点出现时间排序,于是这个点能够插入的地方在([1,sec])之间,其中(sec)表示第一个所属子树和(1)不同的位置。

    组合数算一下就好。


    7043. 2021.04.03【2021省赛模拟】钩子·Plus

    首先可以给每个位置分配一个((0,1))的随机数(p_i),按照(p_i)从小往大,如果两边没有被标记,则标记当前点。

    假设下标为((-infty,+infty)),如果最终(0)被标记了,当且仅当:对于(l,r)满足(p_{l-1}>p_{l}<dots<p_{-2}<p_{-1}<p_0>p_1>p_2>dots>p_r<p_{r+1}),有(2|l,2|r)

    (p_0=x)。可以算出一边概率为(e^{-x}),两边合起来概率为(e^{-2x})。然后可以积分。

    至于为什么只需要考虑(0),zys说题解很不严谨并将其证了一遍。

    现在考虑搞整个序列。设(dp_{i,t1,t2,t2}(x))表示匹配了((-infty,i])(p_i=x)(i)左边的极长递减序列长度奇偶性为(t1)(t2)(t3)分别表示右边如果接一个极长的递减序列奇偶性为什么时,是否可以让((-infty,i))和序列匹配。此时的概率密度函数。

    转移的时候大力积分。


    7044. 2021.04.05【2021省赛模拟】悄悄话

    (f_i)表示(i)为最后一个的答案。转移时找到(j)满足(s_j)(s_i)的子串。

    维护数据结构,修改时(f_i)挂在(s_i)上,查询时查(s_i)的所有子串上信息的最大值。可以用AC自动机或后缀自动机做,查询的时候枚举(s_i)前缀,跳fail链即可。配合线段树搞。

    时间(O(sum |s_i| sum |s_i|))


    7045. 2021.04.05【2021省赛模拟】数学考试

    和三次函数没有任何关系。

    网络流建图。对于每个变量,从(S)(T)拉一条链,割链上哪条边就代表选择哪些。

    对于限制,就在两条链之间横叉边来限制。如果不满足,那么一定还有边可以流。


    7046. 2021.04.05【2021省赛模拟】迷路深層

    怒敲4k最终它假了。

    暴力就是搞个生成树,对于非树边,把它所在环丢进线性基里。询问的时候,首先必须选两点间任意一条路径,然后再用线性基得到最优解。

    对于区间,可以用回滚莫队+可撤销并查集来搞。每个连通块维护个线性基。并查集中还需要维护当前点到getfa之间的异或和,询问两个点之间的异或和可以直接用它们的这个东西异或起来。

    要线性基合并。右边的部分势能分析可以得到时间是(O(msqrt m lg V))(对于某个数,在合并的时候,可能最高位会减,直到对应位为空插进去,或者最高位减到0。所以一个数的势能是(lg V)),左边的部分不能势能分析时间是(O(msqrt mlg^2 V))

    题解的分析是假的。


    LOJ3110. 「SDOI2019」快速查询(口胡)

    看到洛谷上显示提高+省选-我人傻了

    其实这(t*q)的操作可以看成方便读入(10^7)组询问。以操作(4)分组。现在相当于有个初始数组(a_i),每次乘或加,记进行了(x o px+q)这样的操作,遇到单点赋值的时候,令(pa_i+q=v),解出(a_i),修改(a_i)以及总和即可。单点查答案就是(pa_i+q)

    时间是(O(qlg V+qt))。其中(lg V)是求逆元。


    LOJ3111. 「SDOI2019」染色(口胡)

    套路题。把相邻的有值的两列之间作为一个单位计算。设(f_{i,c})表示处理完前(i)个单位,最后一个单位中的空位颜色为(c)的方案数。预处理(g_{i,S})表示一个长度为(i)的单位内的贡献,(S)表示((1,1),(2,1),(1,i),(2,i))四个位置的关系(哪些相等)。状态不会很多。于是得到了(O(nc))的做法。剩下4分不要也罢。

    据说剩下4分可以用线段树或者用SDOI2019D1T1的方法来搞。


    LOJ3112. 「SDOI2019」世界地图(口胡)

    求出前缀和后缀的MST,然后合并。求(pre_{i})需要(pre_{i-1})和第(i)列合并。合并的时候,两块中的最左边和最右边(不只是左块的右边和右块的左边,因为最终还要处理前缀和后缀合并)设为关键点,对关键点建虚树,虚树上每条边中取最大边。除了这些边,其它的边合并之后都不会边。于是对这些边和新加入的边跑MST,跑完之后维护虚树即可。

    一次合并(O(nlg n)),总时间(O(mnlg n))


    7047. 2021.04.07【2021省赛模拟】染色

    看对斜线染色不爽,把它推一下变成个平行四边形,于是就是对行和列染色。钦定选择哪些行,然后对列染色,要求不存在一行本来没有选,但是穿过它的列全部被选了。设(f_{i,j})表示已经考虑了前(i)行,第(i)行最后留白的列为(j)(j)后面的必须选。枚举下一个不选的行(k),根据(j,i+m,1+k)的关系分类讨论,转移到(f_{k,t})(t)是枚举的最后一个留白的列(可能(t=j)),直接写(O(n^4)),容易优化至(O(n^2))


    7048. 2021.04.07【2021省赛模拟】在泪水化为雪花之前

    转化题意就是要决定(e_i),使得([x^c]prodfrac{1}{(1-p^ix)^{e_i}})为给定的多项式。其中(e_0)可以小于(0),其它非负。

    设最大的(e_i eq 0)(i)(m)。考虑最终搞出的(p)次数的范围,显然最大是(mc)。于是要求(n=mc)。由于只有(frac{1}{(1-p^mx)^{e_m}})([x^{mc}])有影响,所以(e_m)是可以算出来的((inom{c+e_m-1}{e_m-1}=a_{mc}),枚举算出,不会很多,题解说模数(998244353)时打表发现(k)相同的(inom{x}{k})中相等的至多有(3)个)。接下来考虑(a_{mc-1})等于什么,发现它之和(e_m)(e_{m-1})有关,所以可以求出(e_{m-1}),依次类推可以推出更前面的。

    推的过程,维护个(F_k(p,x)=prod_{ige k}frac{1}{(1-p^ix)^{e_i}})。由于(a_{m(c-1)+i}=F_{k+1}(p,x)[p^{m(c-1)+i}x^{c}]+inom{c-1+e_m-1}{e_m-1}inom{1+e_i-1}{e_i-1}),于是可以解出(e_i)

    时间是(O(mcn*c)=O(n^2c))

    (i=0)时,需要讨论(e_i)的正负。如果非负照样计算,如果为负,也能用其它方法计算。我的方法是考虑(a_0=(1-x)^{-e_0}[x^c]),如果(a_0)不为(0),此时候选的(e_0)都做一遍;如果(a_0)(0),于是(-e_0<c)(-e_0)的状态可以由(-e_0-1)推过来。这部分耗时(O(nc^2))


    7049. 2021.04.07【2021省赛模拟】生命游戏

    跟GDKOI那题好像啊况且出题人知道。

    首先分开奇偶,给它转45度,于是可以视作一个矩形,每次往右往上扩张一格。求出每个时间点的面积并,然后前缀和就是答案。

    把数值视作(c)(c+T)的形式。处理大小关系不变的(O(n^2))个区间,每个区间内时间点的面积并是个二次函数,扫描线处理之。得到这个分段函数之后给它前缀和即可。

    时间(O(n^3lg n))


    7051. 2021.04.08【2021省赛】模拟 B 数据结构

    考场写KDT,常数大得只有暴力分。

    可以视作一次询问两个序列的前缀(或后缀),取出两个数满足(y)的限制,要求权值和最大。朴素莫队可以做到(O(qsqrt nlg n)),二次离线可以做到(O(qsqrt n))。也可以直接分块做到(O(qsqrt n))(还是(O(nsqrt q))?)

    正解要用到一次同时询问前缀和后缀。首先对(y)分治,现在处理左边的(r)和右边的(b)。考虑到一个询问,是询问(((-infty,L_i),(-infty,R_i)))(((L_i,+infty),(R_i,infty)))。可以发现两个序列中((-infty,infty))的最大值都会出现,并且如果出现了那么会选。于是取(r)的最大值和(b)的所有值,和(b)的最大值和(r)的所有值作为有效的点对。这样的点对总共有(O(nlg n))个。然后再整个二维数点就可以得到(O(nlg^2 n))的做法。


    AGC053

    A:首先下界(k=min(|a_i-a_{i+1}|))。然后将均分成(k)个序列,对于(a_i),序列编号(从(1)开始)小于等于(a_imod k)的就取(lfloorfrac{a_i}{k} floor+1),否则取(lfloorfrac{a_i}{k} floor)。可以证明这样构造一定满足条件。

    B:合法的答案,当且仅当:从中间往两边,对称绑在一起。如果遇到(01,10)就不变,遇到(00)就加一,遇到(11)就减一,要求最终为(0)并且前缀和大于等于(0)。于是可以看做两个序列(a_i,b_i),钦定(a_i>b_i),一开始全选(a_i)。可以选择(i<j),本来选(a_i),调整为选(b_j)。用个堆从后往前扫,贪心看看当前的(a_i)是否可以替换成后面的。

    C:假设最大数所在数组为(a),另一个为(b)。考虑对于(b_i),如果(b_i>max_{k=1}^i a_k),则它应该要被后面的消去,那么就在后面找到第一个大于它的(a_j),可以证明找更后面的不会更优。于是答案为:对于(b_i),找到最小的(j)满足(a_j>b_i)(max(j-i,0))的最大值就是答案。考虑计算(p(d))表示答案不超过(d)的概率,于是对于任意(i),存在(jle d+i,a_j>b_i)。不妨把(i)从从小往大一次考虑,发现这相当于对于任意(i)(b_ile max(max_{j=1}^{i+d} a_j ,max_{j=1}^i b_j))。从后往前确定(b_i),按照这样的顺序确定(b_i)的时候更后面的(b_i)没有影响。于是(p(d)=2prodfrac{i+min(i+d,n)-1}{i+min(i+d,n)})。容易(O(n))算出所有(p(d))


    联合省选2021

    D1T1:枚举(max),求出最大的(min)。分类讨论分析,最终可以做到除排序之外(O(n))

    D1T2:随便构造出一组解(a)。可以发现对一行(或列)加(x,-x,x,-x,dots)仍然是一组解。令最终的解(a_{i,j}leftarrow a_{i,j}+(-1)^{i+j}x_i-(-1)^{i+j}y_j)。可以转化成差分约束问题,用Bellman-Ford跑(方便判负环)就好了。

    D1T3:大把(O(nm))做法。题目相当于对于每个(u,v),求从(u)(v)和从(v)(u)不经过小于(u)的点,路径权值和最小值最大是多少。用桶优化dijkstra是(O(nm)),但是会TLE。其实可以动态加边,加边后看新增能到达哪些点,BFS一下,这样也是(O(nm)),常数较小。也有floyed的做法,枚举中转点(k)从大往小枚举,算完一层之后统计(u=k)的答案。这样可以避免建反图,并且(i>k,j>k)的转移可以不需要(解释:一条路径转移的过程,可以视作一个折线图,横坐标为路径上第几个,纵坐标为节点编号。每次把纵坐标最大的点删掉,把相邻的两个点连起来。由于这题限制中起点或终点肯定有一个是全局最小值,所以每次操作中,当前点左右两边都小于它),加上这个小优化之后可以卡过去。

    D2T1:分成(u o lca)(lca o v)计算。对于某个点,如果它在序列中,记下颜色为序列上后继的最近祖先。于是可以倍增快速查(u o lca)搞了多少位。对于(lca o v),可以二分最后一位,类似搞搞。于是得到了(O(nlg^2m))的做法。如果换成点分治,就可以省掉倍增,(u o rt)可以(O(1))做,(rt o v)要二分然后(O(1))查。于是时间是(O(nlg m))

    D2T2:不动脑子可以写出一个DP。注意到并不需要记最后一个具体是多少,只需要差分一下,当前这个加多少,后面的一并加多少。于是就可以过了。


    牛客挑战赛049

    A:略

    B:设(s(n))表示各位数的和。先求出(sum s(i)-s(i-1)),再减去(sum (s(i)-s(i-1))[s(i)-s(i-1)<0])。后者存在当且仅当(imod 10=0),进而可以列出式子快速计算。

    C:把操作挂在节点上,从大往小枚举节点编号,每次找到祖先最近的操作。用并查集维护。

    D:回文串长度不超过(20),所以可以枚举回文串,然后直接判定是否在(A)串中。

    E:先手要最小化(A边-B边)。可以把边摊到点上,即边的端点加(0.5),如果(A)选就加,(B)选就减。显然对于最终的方案,异色连没有共线,同色连贡献为(pm 1)

    F:找出所有的环丢到线性基中,询问((u,v))时先异或上dfs树上路径的权值和,丢到线性基里跑。询问权值和要(O(1))LCA,由于线性基固定所以可以分两半做,也是(O(1))。时间是(O(nlg n+Q))的,但是求LCA寻址常数太大所以过不去。正解:设有两个点(x,y),从任意点出发,走到(x)回来,再走到(y)回来,于是答案恰好异或上(a_x xor a_y)。并且由于是二分图,询问两点间的路径长度是固定的。于是答案有两种,就是选择奇数个点或选择偶数个点。有个小trick:安排一位表示奇偶性(设为(2^w),并且(w)是最高位),询问奇数的时候丢(0)进去,询问偶数的时候丢(2^k)进去,最后答案都异或上(2^k)

    G:题目求的是仙人掌上两点间最小割。对于一个环,最小边一定会被割。于是把最小边去掉,其权值加到其它边上。最后形成一棵树。把每位拆开,利用重构树计算答案即可。


    ARC117

    A:对大的那边,(1,2,3,dots)这样构造。另一边除最后一个也这样。

    B:排序后差分,每次相当于选一个大于0的数减一。

    C:把三种颜色看成(0,1,2)。对(x,y)操作变成((-x-y)mod 3)。然后组合数计算。

    D:可以做到(2n-1-直径长度)。以直径端点为根搞个欧拉序,要求最后一个被第一次遍历的点是直径的另一个端点,把每个点第一次出现的时间作为答案。接下来证明这同时也是答案的下界:设最终权值为(w_i),对于排序后相邻的(w_i)(即(w_u<w_v)不存在(w_u<w_x<w_v)),那么有(w_v-w_uge dis(u,v))。只考虑相邻的限制,那么相当于:决定一个排列(p),最小化(1+sum dis(p_i,p_{i+1}))。也就是遍历整棵树的最小时间,按照欧拉序跑最优,此时下界是(1+2n-2-直径长度)

    E:考虑画出前缀和的图像,用个平行于x轴的直线从下往上扫,维护扫描线和折线的交点。假设最低点纵坐标为(0)。设(f_{i,j,k,c,0/1})表示扫到纵坐标(i),已经扫过的点数为(j),已经扫过的点形成了(k)段,题目中问的那个段的个数是(c)吗,开头和结尾是否固定,此时的方案数。转移时枚举(x)表示合并相邻的段(k)次,枚举(y)表示合并段之后在空白中插入了(y)段。于是就可以得到(O(n^7))的做法。可以发现转移之和(x-y)有关,所以可以把(x-y)相同的一起枚举,用个前缀和计算一段合法(x)的区间的贡献,就有(O(n^6))。实际上枚举(i)是没有必要的,安排其它的转移顺序,就有(O(n^5))


    计蒜客2021预赛第一场

    A,B:略

    C:设答案为从((0,0))((n,n))。对于一个三角形区域,某条路径第一次经过位置是三角形的直角边,即((x,y))((x+i,y))((y,x+i)),从这里开始不管怎么走前面连续(len-i)个格子会有贡献。于是可以列出式子,列出式子之后可以前缀和优化。

    D:显然可以得到递推式:(f_{2n}=f_n,f_{2n+1}=f_n+f_{n+1})。考虑搞一棵树,节点(i)权值(w_i=(f_i,f_{i+1}))。于是(w_{2i}=(f_i,f_i+f_{i+1}),w_{2i+1}=(f_i+f_{i+1},f_{i+1}))。答案求(max (w_{i,fi}+w_{i,se}))。假设从((x,y),x<y)开始(k)满层,因为是满层所以可以钦定二元组顺序,于是最优的是((xF_{k},yF_{k+1})),其中(F)为斐波拉契数。把询问范围拆成若干个满二叉树即可。全程高精度。


    Codeforces Round #715 (Div. 1)

    A:考虑对于两个序列(a,b),可以构造出长度为(4n-min (cnt0_a,cnt0_b))。即拉出全为0的公共子序列,然后中间的填一下。于是找到(a,b)满足(cnt0_age n,cnt0_bge n)。如果找不到,那么存在(a,b)满足(cnt1_a>n,cnt1_b>n),同样构造。

    B:可以发现合法的方案能够视作划分成若干个区间,将这些区间中的顺序反转。算出方案数之后从前往后确定即可。方案数是2的幂次的形式,增长较快,按位确定的过程中不用二分当前位是什么。

    D:如果只有一个轮换,可以钦定一个点(x),每次(swap(p_x,p_{p_x})),这样一定能行。并且连出来的是以(x)为中心的菊花。如果有多个轮换,先找到一个(x)(满足(p_x eq x))作为根,对其它点极角排序。众所周知如果(x,y)不在同个轮换,(swap(p_x,p_y))之后就会在同个轮换。所以对极角排序后的相邻点进行这样的合并。(注意相邻点的极角差要小于(pi))合并完之后以(x)为中心连出个菊花即可。


    7065. 【2021.4.24 NOI模拟】樟树

    给第一棵树分块,第二棵树直接扫,类似于回滚莫队地做。

    找管辖点,一个点被它最近的作为管辖点的祖先所管辖。记(len_x)(x)子树中,到(x)路径上没有管辖点的最远点距离。如果(len_xge B)则将(x)变成管辖点。取(B=O(sqrt n))

    所有叶子节点的(B)级祖先形成的树的叶子个数为(O(frac{n}{B})),于是所有叶子的(B)的倍数级祖先的集合大小为(O(frac{n}{B}+frac{n}{B^2}+dots)=O(frac{n}{B}))

    (注意不要取(sqrt {maxdep}),这样可能不能保证块个数)

    用可回退并查集来维护连通性。时间(O(nsqrt nlg n))


    7066. 【2021.4.24 NOI模拟】ehzeux与圆周

    AGC028D


    7067. 【2021.4.24NOI模拟】对称线性规划问题

    现在构造一种方案,最终答案为总和一半。把(i)(4n-1-i)配对。把每行作为一个节点,(i)(4n-1-i)所在的两行之间连边。

    于是形成了(n)个点(2n)条边且每个点度数为(4)的无向图,现在需要选择一些边,使得每个点恰好有两条相邻边被选择。

    对于每个连通块找欧拉回路,路径上的边奇偶分类。可以证明这样一定合法。


    Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)

    A:略。

    B:每次找到最小值,其它的列找到最大值,删掉。

    C:考虑对角线从右上往左下扫过去,发现每次可以唯一地确定对角线上的数值。

    D:O(n2k3)能过。其实最终一定是走一段(frac{k}{2})长的路径再原路返回,因为如果走个环,可以选择前半和后半中较小的。设(f_{x,y,i})表示从((x,y))出发走(i)步最短路程,不用记终点。转移是(O(1))的。

    E:经过细致的分类讨论,可以发现合法的序列是:1. 若干个P+若干个C。2. (P)+若干个C+PCPC...PC+若干个P(C)。前缀和搞一下可以发现这是个二维偏序。

    F(口胡):

    思考的时候似乎看错了题意。我的想法:一个连通块的level相当于从所有叶子结点出发跑最短路,树中最大的(dis)(这里和题目已经偏了),也就是取两个叶子(u,v),最小的(frac{dis(u,v)}{2})。考虑所有连通块的level不超过(lim)的情况。于是可以DP,设(g_x)表示(x)子树中(x)不选的方案数,(h_x)表示(x)子树中(x)选并且保证(x)所在连通块已经满足条件的方案数,(f_{x,l,0/1})表示(x)子树中(x)选未保证(x)所在连通块满足条件,且距离(x)最大的叶子距离为(l),是否强制(x)为叶子节点的方案数(好像(0/1)可以去掉)。时间是(O(n^3))

    题解做法:考虑level不超过(lim)的情况。设没有选的点为黑点,那么这等价于每个黑点画个半径为(lim+1)的圆,要求并覆盖所有点。于是可以DP,如果子树内存在未覆盖的点,则记其最深深度;否则,记下可以向上延伸多少。注意并不需要同时记未覆盖点的最深深度和向上延伸多少,因为如果它后来被覆盖了,那么覆盖它的那个点向上延伸肯定比这里记的多。


    LOJ3048. 「十二省联考 2019」异或粽子(口胡)

    前缀和,建Trie,维护每个点和其它点异或第几大在哪里。把这些第几大丢进堆里,每次取最小的,然后找更大的点重新丢进堆里。可以直接用可持久化Trie,也可以直接用Trie,然后(k)变成(2k)。时间(O(klg V))

    有个和(k)无关的做法:先用(O(nlg V))的时间二分出第(k)大具体是什么,对于大于第(k)大的,枚举一个值,要计算它异或上Trie中(O(lg V))个子树中的值的和,相当于排序后序列中(O(lg V))个区间。分开每位计算,前缀和即可。时间(O(nlg^2V))


    LOJ3049. 「十二省联考 2019」字符串问题

    建出Trie在上面连边然后跑最长路。可以对反串建SAM从而建出后缀树,然后把关键点在后缀树上定位,不在后缀树的整点上的点另外分配标号,建图直接跑即可。时间(O(nlg n)),这个(O(lg n))来自对点定位。

    有个想法:直接建SAM,用SAM的转移边建图。实现过之后发现这样是假的,因为一个点代表长度在某区间内的互为后缀的串,如果从一个串(根据点和长度确定),往后跑到一个点,某个串对应点是那个点但长度小,这时候就不合法。


    6152. 【GDOI2019Day2模拟2019.4.29】Endless

    权值从小到大枚举。找平方串套路:枚举长度,设立观测点,如果相邻观测点的LCP和LCS之和大于等于长度,则有平方串,这些平方串的开头在连续的区间。

    支持两个区间合并,ST表+并查集即可。


    7068. 【2021.4.28 NOI模拟】隔离

    平面图满足(C=F+V-E),其中(C)是连通块个数,(V,E,F)分别是点、边、面(不包括最外面)。

    算矩形框住了哪些点、边、面,边可以看做矩形,面可以预处理出来,也能看做矩形。然后做四维偏序,(O(nlg^3 n))

    处理面的时候,把每个点的出边极角排序,从某个点开始选一条边开始跑,到下一个点找这条边的后继继续跑,最终肯定能找到环。每条边跑过就删掉。这部分可以用map实现。还要判断是否是最外面,求一遍有向面积,如果有效面积是负的那就是最外面,不算。

    为什么不算最外面然后减一?因为并不确定最外面的坐标范围是多少。


    7069. 【2021.4.28 NOI模拟】匹配

    构造(sum_{jsubseteq i} b_{j}=a_i)。容易发现高斯消元之后斜对角线(同时也是每一行非0的数为(b_i)),求(b)用FWT即可。

    模拟即可说明。考虑消到第(i)行,前面(jin[0,i-1])行都满足(M_{j,k}=[jsubseteq k]b_j),由于第(i)行中(M_{i,k}=sum_{tsubseteq iigcap k}b_t)。可以视作对于所有的(tsubseteq i)(t),有(M_{i,k}+=[tsubseteq k]b_t),刚好这部分的贡献就是(M_t)。所以(i)肯定是和(tsubset i)(t)消元,消元之后就变成那样。


    7070. 【2021.4.28 NOI模拟】氪金手游

    (ans_i=sum_k w_k[x^k]sum_{l=1}^rprod_{i=l}^r(1-p_i+p_ix))

    点乘可以视作减法卷积乘(x^0)项。记(W(x)=sum w_kx^{-k})

    考虑分治。设当前点为(p)(H_p)为区间外的点的影响(((1-p_i+p_ix))后缀积的和)。

    于是有(H_{lc}=H_p,H_{rc}=H_pf_{lc}+Wg_{lc})。其中(f)表示区间内((1-p_i+p_ix))的乘积,(g)表示区间内后缀积的和。

    由于只需要求([x^0]),所以只需要保留(O(r-l+1))项系数。

    时间(O(nlg^2 n))


    AGC045

    A:考虑从后往前做,记(F_i)是个集合,表示做完了前(i)个,如果当前值为(x)后面能消到0,则在集合中。用线性基来维护。如果遇到了0,就加入线性基;如果遇到了1,看看在不在线性基中,如果在,那么它能被抵消,于是(F_i=F_{i+1});否则它不能被抵消,于是对于任意(x)(x)(x xor A_i)有一个不能被抵消,于是(F_i=empty)

    C:考虑判定。可以视作:每次选择一个长度等于(A)的连续0或长度等于(B)的连续1,将其变成任意值,问能不能还原成初始状态。令(Ale B)(显然可以搞到全1,所以0和1可以互换),如果出现了个长度大于等于(B)的连续1,把这段全部变成0,和两边0的连续段合并,因为(Ale B)所以可以又能够操作这个大的连续段,反转,合并,循环操作到整个序列同色。现在希望让这个1出现,就将所有长度大于等于(A)的连续0全部变成1,然后判断它是否存在长度大于等于B的连续1。可以DP,记所有长度大于等于(A)的连续0全部变成1的状态,设(f_{i,0/1,0/1})表示这样的状态下,最后是(0/1),是否出现过长度大于等于(B)的连续1。需要用数组(g_n)表示长度为(n)的序列,其中两边为1,中间的0所在连续段长度大于等于(A)的方案数,辅助转移。两者时间都是(O(n^2))

    D:显然是按顺序枚举,如果当前点没有被遍历过,就将其所在的环都遍历一遍并点亮。如果某次全部被点亮了那就退出。这相当于,设前([1,A])个中第一个自环为(i)(也有不存在自环的情况),满足([1,i-1])所在的环的并包含([A+1,n])。因为要满足(i)是第一个所以要枚举个(j)容斥,接下来的问题可以表示为三元组((i-1-j,n-A,A-i))。假设是((a,b,c)),先给(a)搞个圆排列划分,即(a!),把(b)插入到(a)的圆排列中,即(prod_{i=a}^{b-1} i),把(c)插入到圆排列中或自成一圆排列,即(prod_{i=a+b+1}^{a+b+c}i)。所以贡献是(a!frac{(a+b-1)!}{(a-1)!}frac{(a+b+c)!}{(a+b)!})。枚举(i,j),时间(O(A^2+n))


    7072. 【2021.04.30 NOI模拟】决战圣诞树

    用生成函数写出式子,然后考虑插值。代入(K)个点值进去,因为是循环卷积所以要满足(x^K=1),也就是模意义下(K)次单位根。找出原根之后(g^{frac{P-1}{K}})的幂就是了。

    现在分别维护(K)个问题。每个问题都是搞一棵树,支持单点乘、邻点乘、子树乘、单点查、子树查。如果没有邻点乘,用线段树或分块可以维护,时间分别是(O(lg^2 n))(O(sqrt n)),线段树中需要多次快速幂。现在有邻点乘,把点按照度数,设定阈值,分成大点小点,改的时候大点在自身打标记,小点暴力改;单点查的时候遍历周围的大点。但是有个问题:子树查。改大点的时候,可以把信息都挂在大点上(数据结构中),在查子树的时候,没有算到的,或多算到的信息只会和(u,v)有关,直接去掉或加上即可。

    但是因为不能直接对0求逆元,所以这个方法可能会挂。尽管如此还是能过。不过再进行一些修改应该也可以搞。

    事实上可以搞个序,先遍历儿子,在递归遍历儿子的子树。这样儿子连在一起,子树(除了自身)也连在一起。于是邻点的问题就解决了。

    至于快速幂的问题,因为模数不大,所以可以算出每个数是原根的多少次方,以及原根的多少次方是什么。于是可以(O(1))算。

    最终每次操作时间(O(lg n))但是好慢。


    7073. 【2021.5.4 NOI模拟】拆分

    (h)扩展。枚举(m),对(a)差分得到(c),要求(c_1ge 1,c_ige k)。容易列出式子(sum_m h_m[x^{n-m-frac{km(m-1)}{2}}]prod_{i=1}^mfrac{1}{1-x^i})

    如果(k>0),合法的(m)(O(sqrt n))的,直接算。

    如果(k=0),重新看原题,发现就是求拆分数第(n)项,即([x^n]prod_{i>0}frac{1}{1-x^i})。求这个东西有很多方法,可以借助五边形数,需要求逆;也有个高级做法:画出Ferrers图(假设(n=sum a_i),将(a_i)从大到小排序,第(i)列放(a_i)个方格),枚举((1,1))为左下角的极大正方形的边长(h),剩下的两个部分都是要求每个数不超过(h)的拆分,列出生成函数就是(sum x^{h^2}(sum_{i=1}^hfrac{1}{1-x^i})^2)。于是时间(O(nsqrt n))

    卡常:1. 对五边形数多项式求逆的时候,不要一开始把有值的地方存在某个数组然后遍历这个数组,在求逆的过程中当场算五边形数,常数小一些。2. 两个int相加之后取模,如果用if,在本地不会变快,在OJ上变快了?

    另外(k=0)时,结合两种做法,得到(sum_m[x^{n-m}]prod_{i=1}^m frac{1}{1-x^i}=[x^n]prod_{i>0}frac{1}{1-x^i}),不错的发现。


    7074. 【2021.5.4 NOI模拟】集合

    转化为取补集求并,找第一个不在并中的位置。枚举(r),对于每个位置维护最后一次被覆盖的时间。修改就是区间取max,查询就是找到第一个最后被覆盖的时间小于(l)的位置。

    时间(O(nlg n))


    AGC040

    A:显然局部最小值可以设为(0),确定这些值之后其它值很好贪心。

    B:求出(maxl,minr)。分区间交是([maxl,minr],[dots,dots])([maxl,dots],[dots,minr])两种情况讨论。前者直接算,后者枚举第一个区间交的右端点时多少然后计算。

    C:假如没有C,可以把奇数位的AB翻转,变成了每次只能选择两个相邻不同的,将其删掉。显然有解的条件是(cnt_A=cnt_B)。现在有了C,相当于可以任意地将C变成A或B,因此有(|cnt_A-cnt_B|le cnt_C),计数即可。稍微推下式子就是([x^frac{n}{2}y^frac{n}{2}]frac{1}{(1-x)(1-y)}(1+x+y)^n)。粗暴的做法是展开,变成计算(sum_{i=0}^{n/2}inom{n}{i}sum_{j=0}^{n/2}inom{n-i}{j}),可以维护(f(n,m)=sum_{i=0}^minom{n}{i})(f(n,m)=sum_{i=0}^minom{n}{i}=sum_{i=0}^minom{n-1}{i-1}+inom{n-1}{i}=2f(n-1,m)-inom{n-1}{m}),于是能(O(n))计算;简单的做法是计算不合法的方案数,即((1+x+y)^n)展开式中(x)(y)次数大于(frac{n}{2})的,因为不可能同时大于(frac{n}{2})所以很好计算。


    6215. 【NOI2019模拟2019.6.14】硬币游戏

    可以看成:价值为(a_i)的,大小为(1)的物品,和价值为(a_i+b_i)的,大小为(2)的物品。

    贪心:先将两种物品从大到小排序,各选一段前缀。当空间加一时,先加入下一个大小为(1)的(如果没有就丢掉个大小为(1)的放个大小为(2)的),然后尝试用大小为(2)的替换两个大小为(1)的。时间可以做到线性。


    6216. 【NOI2019模拟2019.6.14】序列计数

    暴力可以这么做:假设有个大小为字符集的表(s_i),从左到右扫,设当前字符为(c),对于(i eq c)(s_i'leftarrow s_i+s_c),并且答案加上(s_c)

    根据这个矩阵乘法,朴素做法可以做到(O(nC^3+qC^2lg n))

    发现这个矩阵有逆,把答案处理成:([1,1,dots,0]A_{l}A_{l+1}dots A_{n}A_{n}^{-1}dots A_R^{-1}A_{R+1}^{-1}[0,0,dots,1]^T)的形式,前半和后半都可以预处理。

    可以做到(O(nC^2+qC))。(在乘一个矩阵的时候,这个矩阵中有值的位置是(O(C))的,所以只需要(O(C^2))做乘法)

    写出来之后整理一下可以发现能够简单优化至(O((n+q)C))


    AGC043C Giant Graph

    暴力可以想到按照(i+j+k)从高到低确定,同层的不会有边,直接贪心即可。

    考虑一维的求最大独立集的过程:设(f_i)表示是否选(i),从后往前做,如果(i)存在后继被选了,则(f_i=0)。发现其实可以视作:在这个DAG上的Nim游戏,从某个的出发如果先手必胜则(f_i=0)

    可以推广到三维的情况,相当于三个Nim游戏的叠加。于是算出sg函数,统计(sum[sg_{1,i} xor sg_{2,j} xor sg_{3,k}=0]w_iw_jw_k)

    FWT可以做,也可以暴力卷积,因为sg函数的取值是(O(sqrt m))


    AGC041C Domino Quality

    (nle 3)的时候特判。

    可以手动构造出(n=4,5,6,7)时每行每列只有(3)的方案。用这些方案拼接,在对角线处放即可。


    AGC039C Division by Two with Something

    操作可以视作:将二进制(从高到低)的最后一位取反之后移到最前面。

    进一步分析,可以得到这个二进制应该长成:(Aoverline AAoverline Adots Aoverline AA)的形式。上划线表示取反。找到这个极小(A)(|A|)就是操作次数。

    极小通过容斥得出。先设(f_{L})表示长度为(L)的不保证极小的(A)有多少个,通过给读入字符串的前(L)位扩展成如上形式和原字符串比较,得到(f_L)(s)(s+1)的形式。然后容斥得到(g_L)(g_L=f_L-sum_{d|L,d<L}[frac{L}{d}mod 2=1]f_d)


    AGC038C LCMs

    根据(lcm(a,b)=ab/gcd(a,b)),做个min卷积平方,每个位置除以下标的和就是答案。


    AGC037C Numbers on a Circle

    如果(a_i)刚刚被操作,那么(a_i>a_{i-1}+a_{i+1})

    考虑倒推,对于(b_i>b_{i-1}+b_{i+1})的位置,如果(b_i>a_i),则(b_i)应该被修改,并且在它改变之前(b_{i-1},b_{i+1})都不变,不会影响它的条件,所以(b_i)可以立即修改。

    维护个堆,每次找出最大的,贪心地修改它。因为(b_i)变成(b_imod(b_{i-1}+b_{i+1})),必定减半,所以时间是(O(nlg nlg V))


    AGC035C Skolem XOR Tree

    显然(n)为二次幂的时候不行。

    可以把形如(2k,2k+1)的配对。连边((1,2k),(2k,2k+1),(1,(2k+1)'),(1,(2k)'))

    如果(2|n),设(x=lowbit(n),y=n-x),连边((x,n),(y',n'))


    AGC034C Tests

    每场考试可以看做关于(a_i)的函数,这是个分段的一次函数,两端斜率分别为(l)(u),分界点在((a_i,0))。将所有分段函数的最低点移到(y=0)处,于是我们希望决定(a_i)使得函数和达到(sum l_ib_i)

    有结论:最优解中,至多只有一个(a_i)取到了((0,X)),其它的不是(0)就是(X)。证明可以考虑,如果有两个取((0,X)),根据其在各自函数中所在的段分类讨论,发现都可以调整。

    按照取(X)之后的贡献排序。枚举哪个取了((0,X)),然后二分一段取(X)的前缀即可。时间(O(nlg n))


    7079. 【2021.5.9 NOI模拟】消除

    可以转化成:随机一个排列,按照排列顺序操作。如果当前点的祖先没有操作过,(cnt)加一。求(cntle K)的概率。

    (f_{i,j,k})表示(i)子树中,有(j)个点有贡献,排列中位置在最后一个有贡献的点后面的点有(k)个。于是可以做到(O(n^4))

    观察转移式,可以发现(j)这一维是个纯的卷积。于是用插值将这一维搞掉,时间优化到了(O(n^3)),空间优化到了(O(n^2))

    其实转移的时候,(k)这一维也可以利用卷积转移,时间理论可达(O(n^2lg n))


    ARC118

    A:因为分母为100,所以可以100为循环节操作。搞出100以内有多少个空的,然后算出在第几个循环节就可以找到了。

    B:首先可以二分答案,然后得到每个(B_i)的取值范围,分别求其上界和下界的和得到(sum B_i)的取值范围,如果(m)在范围内就有解。二分出来之后一个个确定即可。如果用实数精度要开大(我开到1e-14),其实也可以用整数来二分。

    C:先放入6,10,15,然后放入6或10或15的倍数即可。

    E:考虑走到((i,j)),然后确定((0..i,0..j))中的点。从((i,j))转移到((i+1,j))的时候,决策一下第(i+1)行的点放在哪里,分在((i+1,1..j-1))((i+1,j+1..n))讨论。发现这样要记一下((0..i,0..j))中已经确定了多少个点。于是可以记状态(f_{i,j,k,0/1,0/1}),表示走到((i,j))((0..i,0..j))中确定了多少个点,其中(i)行,(j)列,是否有点的方案数。然后可以做到(O(n^3))的复杂度。


    CF1515G

    类比一下无向图,边权异或的问题:

    对于每个强联通分量分别做。任取一个点,记其为(rt),然后搞一颗外向树,记到点(i)的边权和为(phi(i))

    因为肯定存在从(i)(rt)的路径,假设长度为(s),对于任意模数(P),从(i)(rt),然后绕(P-1)次长度为(phi(i)+s)的圈回到(rt),总长为((P-1)phi(i)+Psequiv -phi(i)pmod P)。所以可以直接认为(i)(rt)有长度为(-phi(i))的路径。

    每个点能走的环长的集合都等于根节点,因为可以先走(-phi(i))(rt),走完环之后再走(phi(i))回来。

    于是如果有一条非树边((u,v,w)),可以认为贡献了一个(phi(u)+w-phi(v))长度的环。

    求出所有环的gcd,于是能走的环长就是gcd的倍数。剩下的问题就好搞了。


    7082. 【2021.5.10 NOI模拟】中单

    由于结果是取max,可以将原来的限制拆成多个由更紧的限制组成的子问题,并且这些子问题的并恰好为原问题。

    在这题中,相当于枚举(s_0,s_1,s_2)的相对顺序,然后转化为了6个问题。每个问题都是个三维偏序,加上个询问最大异或。

    我的做法是对答案进行整体二分。从高位往低位,在当前层中,算出哪些询问可以取到1。接下来当前位为0的修改往左走,为1的修改往右走;询问如果可以取到1就往相反否则相同的地方走。然后里面就是个三维偏序,又因为询问只需要问是否存在点在询问范围内,所以最后一维只需要存个最值。于是(t)排序,(x)用cdq归并,(y)存最值就可以搞定了。总时间(O(nlg nlg V)),空间(O(n))

    其他人的做法阴间一些:先对(t)排序,套cdq分治:建Trie,然后按照(x)的大小归并,如果是修改就在Trie上改(y)的最小值,如果是询问在Trie上二分。时间也是(O(nlg nlg V)),空间是(O(nlg V))劣一些。


    6213. 【NOI2019模拟2019.6.13】String

    稍微分析可以可得一定是尽量匹配直到不能匹配划分为一段。

    简单做法:建出SAM,然后算出(g_{u,v})表示(u)为开头,结尾下一个为(v)的一段最短是多少。然后倍增+矩阵乘法。

    更高明的做法:找到最长的长度(len)满足所有长度为(len)的子串都被包含。接下来连边,边权都相当于是(len)。如果连出的图有环,就找最小环长;如果无环,就找最长路。再算一波就可以得到答案。


    6252. 【NOI2019模拟2019.7.4】天涯海角

    可以看成:修改是对祖先链进行(pm1)操作,以及改变某个点是否存在;查询是查整棵树(>0)的点权数。

    我的做法:树剖,对于每条重链分块,长度为(sqrt {len})。对于每个块,一开始排好序,用链表维护(权值相同的压在一起),并且维护一个指针。整体加减的时候移动指针,散块修改的时候对链表上节点进行操作。总时间(O(nsqrt n))。当把链表从动态分配空间+没用的点不删变成静态分配空间+没用的点删,从2s+变成了500ms+。

    有个更好的优化:不用链表,直接维护排序后的序列(权值相同的还要压在一起)。散块修改的时候,将修改的点和不修改的点分开,然后归并。因为寻址连续,所以优化效果应该更加显著。

    更简单的做法:每(O(sqrt n))次定期重构,对关键点建虚树,每条边维护桶和tag。可以做到每个询问块(O(n))解决。总时间(O(nsqrt n)),常数小,代码短。


    7083. 【2021.5.10 NOI模拟】骚猪(口胡)

    考虑如果有区间([l,r])([L,R])包含,那么([l,r])应该选择和([L,R])不同的颜色,否则不会更优。于是找到没有被其它区间包含的区间的集合,记为(W)。其它的集合选择一个(W)中包含它的区间(记为父亲),最后取相反的颜色。

    假设有解:如果(|W|)为偶数,那么可以给(W)交替分配颜色。对于某个位置,被(W_i)包含,若同时被(W_{i-1})(W_{i+1})包含,则没问题;否则因为假设有解,一定存在其它区间包含它,并且那个区间的父亲是(W_i)

    如果(|W|)为奇数,也是交替分配颜色,然而(W_{i-1},W_i)颜色相同。如果某区间只被其中之一包含则没有问题;如果被它们的交包含,又要要求还有个儿子区间包含它。因为有解,所以在某个解方案中,由鸽巢原理必定存在(i)(W_{i-1},W_i)同色,并且它们的交也满足条件。所以说如果有解,在(i)的所有取值中,至少存在一种使得交替分配颜色有解。

    于是枚举(i)判断。加速判断:对于(W_{i-1}igcap W_i)内的点,要满足被至少一个儿子区间包含,或被至少三个(W)区间包含;对于不在(W_{i-1}igcap W_i)的点,要满足被至少一个儿子区间包含,或被至少两个(W)区间包含。


    7087. 【2021.5.18 NOI模拟】差异

    其实就是把区间分段,要求每段中并不为空。

    一种做法:设(f_i)表示(i)结尾的段数最少是多少。(f_i)可以直接贪心或DP得到,显然(f_i)单调不降。然后还要维护方案数(g_i)。普通暴力是(O(n^2)),用单调栈+线段树就可以(O(nlg n))了。

    另一种做法:考虑设(f_{i,j})表示到第(i)个,结尾为(j)的最小段数。归纳证明,对于(f_i),大概是(mn+1,mn,mn+1)三段。用线段树维护即可。


    7087. 【2021.5.18 NOI模拟】差异

    原来长度为(c)的环会分成(gcd(c,k))(frac{c}{gcd(c,k)})的环。反过来,枚举分成的环(l),先统计这个环有多少个,然后划分,如果一个块个数(c),则要满足(c=gcd(lc,k))

    于是可以写个DP进行转移(其实这转移类似于exp)。时间复杂度(O(nd(k)))(d)表示约数个数。

    实际上时间瓶颈在于统计环,因为寻址不连续。


    7089. 【2021.5.18 NOI模拟】排序

    既然求出前k大,直接A*。估价用网络流来搞。只要每次估价都准确,那么估价的总次数最多为(2nk)

    于是时间复杂度为(O(nkMAXFLOW(n,m)))

    实际上由于相邻的状态之间变化比较小,所以可以直接带修网络流(支持加边删边)搞。

    (话说这里的A*应该是可以不用优先队列的,直接递归即可,用带修网络流的话就可以不用存多个图,会不会快一些?)


    CFgym103069 2020 ICPC Asia East Continent Final

    B:离线。考虑一个矩形贡献在矩形最小值处。枚举矩形的上下边界,中间求最小值,于是变成一个序列数多少个区间最小值是什么。笛卡尔树即可。

    C:把(x)写成(x_0x_1dots x_{63})的形式,若干次变换之后,其中每一位可以表示成一些(x_i)的异或。得到了(f^i(x) mod i)等于多少,用(mod lowbit(i))得到最后几位的信息。于是就得到若干条方程,一共有(sum_i lg(lowbit(i)))条方程,大概是(O(n))。并且(nge 50),猜到自由元不是很多,枚举之后挨个判定即可。

    D:枚举相交部分的两个端点,显然起点终点和端点之间,端点和端点之间都是最短路。得到若干个((a,b))表示(a)个重复路,(b)个不重复路。由于二维偏序更大的可以不用计算,去掉那些之后剩下(O(n))个。对于每个,用二分之类的做法搞一搞。

    G:枚举右端点,维护每个左端点的信息。可以视作:有一堆黑白点,支持:1. 区间黑白反转。2. 区间白点权值加一。3. 询问区间权值和。线段树上节点上维护:权值和,黑白点个数。标记维护反转标记,以及权值加一的标记(分别是黑点加的标记和白点加的标记)。

    I:按照时间顺序做。求出上一个活到最后的人存活到的时间,对于这个人,先计算它在被挡刀时候能否活下来,然后计算它没有被挡刀的时候活多久。用线段树二分维护。细节有点多。


    ARC119 D - Grid Repainting 3

    考虑给红点的行列连边(行和列分别分配点)。一次删除相当于删去一个点。

    对于一个连通块,随便搞一棵生成树,剥叶子地删,最终剩下一个点。只要连通块大小大于等于2就可以决定它在哪边。

    先求出两边孤立点的个数,接下来决定每个连通块最终保留的点,显然放在孤立点多的那边。


    ARC119 E - Pancakes

    拆绝对值,二维偏序即可((l<r)那维可以去掉)。


    6248. 【NOI2019模拟2019.7.3】光影交错

    (E_i)表示当前和为(i)的时候,往后走的期望。大概可以列出(E_i)关于(E_{i-1})(E_{i+1})的式子。

    根据(E_{-infty}=0)(E_{+infty}=frac{1}{p}),把边界开到(3*10^6)级别。按照套路,把式子转化成(E_i)(E_{i+1})的关系即可。


    6250. 【NOI2019模拟2019.7.3】魔法咒语

    生成函数计算即可。


    6244. 【NOI2019模拟2019.7.1】为了部落

    搞一个虚根,虚根和森林中每个根连边。相当于钦定虚根度数为(m),与虚根相连单点点度数不超过(K+1)

    借助prufer序列来计算即可。用点DP。注意组合数要分解质因数算。


    7091. 【2021.5.26 NOI模拟】矩阵

    首先想到burnside。考虑枚举排列(p)(q),贡献为(c^{sum_{xin C_p,yin C_q}}gcd(x,y)),加起来,最后乘(frac{1}{n!m!})

    因为(nmle 1000),所以较小值不超过(31),可以暴力枚举其划分数,后面DP搞。

    (nle m),时间(O(D(n)m^2))


    7092. 【2021.5.26 NOI模拟】喂鱼

    回滚莫队。现在要支持在序列上加入点,并查询最长段。可以在每段的端点处记另一个端点是什么,就可以(O(1))地加入并更新最大值。时间(O(nsqrt n))

    实测这不一定比可撤销并查集快(


    ARC120E 1D Party

    相邻两个相撞之后一定会反弹,否则不会更优。反弹可以看做穿过,于是相对位置发生了变化。

    题目可以转化为有个排列(p_i),一开始(p_i=i),对于每个(1le i<n)都要进行一遍(swap(p_i,p_{i+1})),可以任意规定顺序。最小化(frac{1}{2}max |A_i-A_{p_i}|)

    显然有DP:设(f_{l,r,u,v})表示搞([l,r])这个区间,(l)处为(A_u)(r)处为(A_v),其它位置原样。转移就枚举下一次搞(i,i+1),那么可以分操作两边((i=l)(i=r-1))和操作中间考虑。如果一开始就先将(max |A_i-A_{i+1}|)贡献入答案,操作两边只需看做往中间缩而不产生任何贡献。

    观察DP,发现实际上就相当于:给序列分段,每段长度至少为(2),然后在两个序列交界处两点交换,最终贡献为每段的头尾的差。

    只需要处理长度为(2)(3)的段。更长的段可以再分,不会更劣。写出另一个DP即可。


    LOJ3324. 「SNOI2020」取石子

    打表可得,((n,k))必胜当且仅当(kge lowbit(n-1)),其中(lowbit)是斐波拉契进制意义下的。

    斐波拉契进制下数位DP即可。


    7093. 【2021.5.28 NOI模拟】一道计算几何的模板题

    考虑求出每个(x)对应的最大和最小的(y)

    可以发现(x)(y)分别的变化都是( ho)的形状,进入循环节前暴力统计。对应(y)环上的每个点处理出跳(x)环周期步之后到哪,然后倍增处理。

    其实也可以:(假设求最小(y)),从小到大枚举能走的(y),看看能贡献到哪些(x)。把(x)连成环(跳(y)周期步),每次就是环上一段区间上未标记的位置标记。用并查集维护之。


    7094. 【2021.5.28 NOI模拟】菜肴挑选

    如果(n)为奇数:可以看做一个等分圆,对所有等腰三角形做。这样每种边出现3次。

    如果(n)为偶数:先对前(n-1)个重复上面的操作,然后对所有长度为2的边和(n)做一次,对所有长度为1的边和(n)做两次。然后再对前(n-1)中所有腰长大于等于2的等腰三角形做一次。


    7097. 【2021.5.29 NOI模拟】Rhuzerv

    阴间题意看了我3.5h

    枚举长度,填数和染色就可以分开计算了。前者直接算,后者用生成函数稍微推一下。实际上后者也有组合意义:选择(2(L-m))个点,这些点分别作为选择的黑点、白点这样交替,且最后一个点是白点。两个白点之间都染黑。


    7098. 【2021.5.29 NOI模拟】究竟

    主要思想:对每个串建SAM。对于(SAM_i)中某个点(x),如果(x_{trans(c)}=NULL),则将其赋值成({S_{i+1}}_{trans(c)})。相当于:在当前串中匹配某个子串,如果能匹配就匹配(转移边不变),否则接到下一个串继续匹配。

    用DP来实现一下,可以搞出({S_{i}}_{trans(c)})({S_{i+1}}_{trans(c)})之间的转移,用矩阵来表示。一段区间的答案最终可以写成:(常数行向量*若干矩阵*某列向量)的形式。分治搞一搞,用一些不特别的技巧即可。

    (实际上也许可以通过修改转移矩阵,使得求子区间和,变成直接求区间乘积?)


    7096. 【2021.5.29 NOI模拟】签door♂题

    可以发现答案的前一半一定是1到n。

    把1到n看做黑点,把n+1到2n看做白点。每个连通块记个(c_0,c_1)表示未确定的黑点和白点数,可以视作每次选择不在连通块内的一个黑点和一个白点,将对应连通块合并并将(c_0)(c_1)减一,变成个子问题。

    考虑一号点。如果可以找到一个和它不在同个块中的白点,匹配之后变成子问题;如果找不到,说明剩下(n)个白点跟它同块,块内至少有(n)条边,又因为题目是只连好了(n-1)条边,所以不存在。

    于是按位确定,用可并堆可以做到(O(nlg n))


    计蒜客2021复赛

    一如既往地没有质量。

    A:直接DP,线段树维护。

    B:建支配树之后随便DP。

    C:建重构树。统计子树内颜色个数可以:用树状数组,下标为最新出现的时间,将颜色挂在上面。进去子树前记一下时间,出来时用总的减去在进去之前的。

    D:用矩阵维护,LCT搞一搞。矩阵的等比数列是可以快速幂求的。另外这题模拟LCT暴力换根是可以过的。


    ARC121

    C:考虑每次将最小值往前提,如果奇偶性不对,搞一些变换使奇偶性调回来。分类讨论一下。

    D:如果必须选两个,一定是开头匹配结尾。可以选一个,相当于加入若干个0。

    E:考虑容斥。(dp_{i,j})表示(i)子树至少有(j)个祖先走到后代的(不合法),直接转移。


    UR21 A 士兵调度

    一种构造方法:考虑现在搞成一个(l*l)的矩形,然后给其增加一行一列。增加的时候就从远方移动一个点过来。

    因为(m)可能很小,所以先围一个(sqrt{n-m})边长的矩形,再进行这样操作。次数大概是(sum_{i=n-m+1}^n sqrt i)

    题解中有个上界分析:如果一行中有(a)个点选择列,那么每列有超过(a)个点。于是有(a^2le n)。如果要改变这行一些点从选列变成选行,那么至多会变化(sqrt n)个点。每次合并的时候较小的那边用启发式合并来分析,那么上界为(msqrt n+nlg n+O(n+m))


    7100. 【2021.6.1 NOI模拟】皮皮虾

    答案是行列式,对角线是(F),不是对角线是(G)

    (A_n(x))表示对角线是(x),不是对角线的位置是(1)。用第一行和其它的消,可以变成子问题,即(A(x)=frac{1}{x^{n-1}}(x-1)^{n-1}A_{n-1}(x+1)x)

    仔细观察可以发现其通项:(A_n(x)=(x-1)^{n-1}(x+n-1))

    于是答案为((F-G)^{n-1}(F+(n-1)G))。可以快速幂。因为(F,G)项数不多,所以也可以直接用点值搞,或者短多项式求幂。


    7101. 【2021.6.1 NOI模拟】人生赢家

    发现当(nge 3)时,只需要考虑相邻两个之间的字符的关系。

    (F_{A/C/G/T})表示从什么开始的生成函数,用(x_A,x_C,x_G,x_T)的多项式表示。列出方程,解一下,就可以得到式子。

    实际上也可以通过路径的特征进行分段,然后组合意义。

  • 相关阅读:
    《SQL Server 2000设计与T-SQL编程》
    sql语句优化 (转)
    SQL Server优化50法(转)
    (转)SQL 优化原则
    sql 锁
    后台服务标准化运营
    ReactNative For Android 框架启动核心路径剖析
    手机QQ会员H5加速方案——sonic技术内幕
    微信支付商户系统架构背后的故事
    [干货] 有了微信小程序,谁还学ReactNative?
  • 原文地址:https://www.cnblogs.com/jz-597/p/14594341.html
Copyright © 2020-2023  润新知