[JSOI2019]神经网络
考虑把依次经过的树写成一个序列并放在一个环上,那么这个序列所要满足的条件就是开头必须是(1),相邻的两个数不相同且首尾不能均为(1)(如果均为(1)的话会算重)。
对于每一棵树,我们可以设(f_{i,j,0/1/2})表示以(i)为根,将这棵树划分为(j)条链,(i)已经连了(0/1/2)条边的方案数,这样就可以把一棵树划分为(i)条链的方案数算出来了,因为这题链有方向,所以节点数(>1)的链方案要乘(2)。
令(f_i)表示某棵树划为(i)条链的划分数,构造EGF。
首先我们不考虑(1)的情况,那么有
其中(i!)是他们内部排列数,({i-1choose j})是强制相邻的两个并起来的方案数,((-1)^j)是容斥系数。
把(1)考虑进来,就是我们钦定(1)中的第一个数必须放在第一个位置除去环的限制,它不参与内部排列也不参与外部排列,那么有
最后再减去考虑首尾均为(1)的情况,那么就是最后一个点不参与外部排列但参与内部排列:
最后把所有EGF卷起来把([x^i])乘上(i!)再相加就是答案。
代码
[JSOI2019]精准预测
这个题的约束条件很像( ext{2-sat}),往这方面考虑。
题目所给的约束条件可以直接连边,还有约束条件的话就是如果一个人在(t)时刻活着那么在(t-1)时刻活着,在(t)时刻死了那么在(t+1)时刻死了。
然后再看每个点(T+1)时刻死了能到达多少个其他点活着的就行了,假设有(cnt)个,那么该点的答案就是(n-cnt-1),这个可以通过( ext{bitset})优化拓扑排序dp求出。
但是( ext{bitset})还是存不下所以要分段跑,注意如果一个点必死那么它不能算进贡献。
代码
[TJOI2018]party
考虑我们算LCS的dp:(f_{i,j})表示第一个序列到(i),第二个到(j)的LCS长度。
那么有(f_{i,j}=max{f_{i-1,j},f_{i,j-1},f_{i-1,j-1}+[a_i=b_j]})
如果我们现在固定(i),对于相邻的(j),(f)的差值不超过(1),可以考虑把对于每个(j)的增量状压下来。
然后对于一个 mask 的转移可以预处理出来,对于NOI
的限制再多记一维状态就可以了。
代码
[NOI2016]循环之美
考虑最简分数(frac ab)在(m)进制下是纯循环小数的条件:
第一位的余数是(amod b),第(x)位的余数是(a imes m^xmod b),
我们要满足的条件就是(aequiv a imes m^xmod b)。
因为((a,b)=1),所以(m^xequiv 1mod b),若((m,b)=1),(x=varphi(b)),否则无解。
所以题目转化为
然后推下式子:
令(f(n) = sum_{i = 1}^n [i perp k], g(n, k) = sum_{i=1}^n mu(i)[i perp k])
显然(f(n) = leftlfloor frac nk
ight
floor f(k) + f(n mod k))
推下(g):
当(k=1)时无法递归,需要杜教筛(mu),然后就做完了。
代码
[TJOI/HEOI2016]字符串
如果没有右端点的限制就直接( ext{SA}+)主席树查区间前驱后继就好了,但是现在有右端点的限制我们可以考虑二分将这个限制去掉,再用主席树查询即可,复杂度(O(nlog^2n))。
代码
[NOI2017]蔬菜
考虑卖一定数量的菜所能带来的最大收益:我们将菜按钱数从大到小加入,并且选能选的最后一天放(可以用并查集维护),因为后面的天可以,前面的天就一定可以,所以最终查询直接查询卖(m imes p)棵菜能够赚到的最多的钱数即可,细节详见代码。
代码
[CEOI2017]Mousetrap
假设所给的树以陷阱为根。
考虑两点相邻的情况,设(f_x)为以(x)为根的子树下来再上去所需的最小步数,那么每次你最优肯定是堵(f)最大的这时候老鼠就会往次大的(f)走,(f)可以dp出来。
问题是现在不相邻,对于往上走再往下的情况我们不好处理,那么考虑二分答案( ext{mid}),就可以算出陷阱到鼠的链上哪些点一定要堵住,就可以( ext{check})出来不来得及了。
代码
[HNOI2012]三角形覆盖问题
自适应simpson+玄学调参
代码
[SNOI2019]字符串
后缀排序后就是( ext{ST})表(+ ext{Sort})的事了
代码
[JSOI2019]节日庆典
可以维护出可能出现的最小的后缀的集合,发现集合中的数不超过(log n)个。
证明参考 zsy 的:
简单证一下这个性质:考虑相邻的两个最小后缀(i,j),若(|j|<|i|<2|j|),则说明(i=AAB,j=AB),其中(A,B)均为字符串,且(B)是(A)的一个严格前缀。此时考虑(i=AAB,j=AB,k=B),可以发现无论如何最小后缀都会在(i)和(k)之间产生,(j)不可能成为最小后缀(如果(j)比(i)优,那么一定有(k)比(j)优),由此说明相邻两个最小后缀的长度至少( imes 2),因此数量不超过(log n)。
这题的数据范围较大,所以维护(lcp)时食用( ext{Z-algorithm})维护。
代码
[POI2013] Tower Defense Game
发现如果选择一个没有被其他点覆盖的点的话一定可以覆盖到原来(K)个点之中的一个点。
所以没选则选就好了。
[POI2011] Party
考虑删点。
对于没删的一对点(u,v),如果他们之间没有直接连边的话肯定没在(frac 23N)的团中。
那我们可以把这个(u,v)都删掉,可以保证剩下的点一定构成一个团。
代码
AT3557 Four Coloring
曼哈顿距离转切比雪夫距离。
然后按照
构造块,每个块的大小为(K imes K)就行了。
代码
CF989C A Mist of Florescence
如果题目给我们(50 imes 50)的话那我们就整个利用好。
考虑将(50 imes 50)分为(4)个(25 imes 25)。
在不分割(25 imes 25)的前提下将其他颜色填进来就可以很简单的构造了。
代码
AGC004C And Grid
构造一个集合为奇数行+第一列+原图,一个为偶数行+最后一列+原图。
代码
CF576C Points on Plane
将每个坐标((x_i,y_i))看作区间。然后就是莫队了。
代码
CF618F Double Knapsack
考虑加强题目限制:子集(
ightarrow)子区间。
分别记录前缀和,假设第一个集合的总和小于第二个集合。
从左往右扫第一个集合假设现在的前缀和为(p),用单调指针在第二个集合前缀和中lower_bound,设为(q)。
那么(0leq q-p<n)。
如果为(0)我们就找着了,否则的话根据抽屉原理一定会存在一对(p,q)差相等,减一下就完事了。
代码
[LG3599]Koishi Loves Construction
首先对于第一问,(N)必须要放在第一个。
那么对于所有数的和需要满足(N
mid frac {N imes(N+1)}2),所以(Nequiv 0(mod 2))。
然后构造一个这样的序列即可:(N,1,N-2,3,N-4...)
然后考虑第二问,(N)必须要放在最后一个。
而且需要满足(N
mid (N-1)!),发现(N)只能为(1,4 or ext{Prime}),对于(1,4)我们可以打表。
质数的话可以打表发现(1,frac 21,frac 32,frac 43...frac {n-1}n,n)可以,或者构造原根为(g),像加法那样构造(g^0,g^1,g^{N-3},g^3,g^{N-5}...)。
代码
CF909F AND-permutations
首先考虑第一问,显然有(N)为偶数。
考虑怎么构造,可以想到(i)与(i)按位取反交换,但是这样的话有可能或超过(N)。
设(k)为(N)二进制为中的最高位,(2^k)与(2^k-1)交换,(2^k+1)与(2^k-2)交换,以此类推。那么我们交换了(2^k)到(N),也交换了(2^k-(N-2^k+1))到(2^k-1),剩下了(1)到(2^k-(N-2^k+1)-1),再递归处理即可。
第二问的话,考虑交换((2,3),(4,5),(6,7)...)。
最后会剩下(1)或者(1,N),如果(N)为奇数则剩下(1),直接将前(7)个改为(7325641)即可,小于(7)直接爆搜。
如果为偶数的话(N)为二的幂无解,把(1)和最后三个数的顺序变为(N-1,N,1,N-2)即可。
代码
AT5761 Odd Sum Rectangles
把(mathsf{color{black}{I}color{red}{tst}})的放上来
CF593C Beautiful Function
假设所有圆上的点都过圆心,于是我们可以让(f(i)=x_i,g(i)=y_i),因为两种方法的构造情况其实是一样的,所以在这里我们只考虑(x)。
令(t=|i-x|,xin mathbb Z)
有这样一个式子(1-t+|1-t|)当且仅当(t=0)时有值且为(2),那么我们直接在这个式子外边乘上(lfloorfrac {x_i}2
floor),就可以保证当(x=i)时值为(x_i)了,因为题目保证(rgeq 2)所以(1)的误差没关系。
代码
CF537C Bear and Drawing
发现一个可以画出的树必然是有一个主干和若干个枝条构成的,像下面这样:
那么我们可以将所有枝条中除了Y
字形态的都给剪下来,那么现在树上就剩下了Y
字枝条和主干。
考虑如何判断Y
,就是看它的邻居中是否只有一个没有被剪下来,那么我们再对于主干判断一下有没有一个主干的邻居超过两个主干就好了。
代码
CF750F New Year and Finding Roots
随机从一个点开始,可以通过两次类似于( ext{dfs})的询问确定访问到深度最浅的点(x)以及它的深度。
再从(x)出发类似地继续找到一个深度最浅的点(y),如果(y)的深度是(2 ext{or} 3)就直接往上( ext{bfs}),否则再用类似的方法继续找。
代码
CF1060H Sophisticated Device
首先快速乘是很好模拟的。
然后想办法弄出一个(0)的位置,就是将一个(1)乘上(p),乘法可以食用快速乘。
其他的运算:减法:乘上(p-1),除法:乘上逆元。
看我们如何求出(xy),有(xy=frac {(x+y)^2-x^2+y^2}2),那么现在我们要想办法求出平方。
设(x^2=sum_{i=0}^d a_i(x+i)^d=sum_{j=0}^d{dchoose j}x^jsum_{i=0}^di^{d-j}a_i),可以钦定平方项为(1)其他为(0)然后高斯消元。
平方弄出来这题我们就做完了,写的时候耐点心。
代码
CF1044B Intersecting Subtrees
其实只要用两次操作,第一次从(B)集合中选出一个点找到它在(A)中的位置然后把它作为根,再从(A)中找出深度最浅的点询问在不在(B)中即可。这样是对的是因为根不满足意味着其他点也一定不满足。
代码
CF1146C Tree Diameter
想办法把直径两端分在不同集合:每次按每个二进制位分组即可。
代码
CF830E Perpetual Motion Machine
分情况考虑:
如果存在一个环,那么令环上的点权值为(1),其余点权值为(0)。
如果存在一个度数大于(3)的点,令这个点的权值为(2),和它相邻的点权值为(1),否则权值为(0)。
如果存在两个度数等于(3)的点,令这两个点的路径上点的权值为(2),其余的点权值为(1)。
如果没有度数为(3)的点,说明是很多条链,由简单的不等式知识知道这肯定不行。
还有一种情况比较麻烦,有一个度数为(3)的点,那一定是这个点引出三条链,设这三条链长度分别为(p,q,r),有解当且仅当(frac 1p+frac 1q+frac 1rleq 1),下面进行证明:
设三条链上的点权由远及近为(x_1,x_2...x_p),(y_1,y_2...y_q),(z_1,z_2...z_r),且(x_p=y_q=z_r=v)。
令
那么我们想关注(S=A_x+A_y+A_z+v^2)的正负性,我们将等式两边同时( imes 2),正负性不改变
也就是(2S=2A_x+2A_y+2A_z+2v^2)。
其中$$2A_x=sum_{i=1}^{p-1}frac{i+1}{i}(x_i-frac {i}{i+1}x_{i+1})^2-frac {p-1}{p}v^2=F(x)-frac{p-1}pv^2$$
(A_y,A_z)同理,这里不展开。
然后(2S=F(x)+F(y)+F(z)-frac {p-1}{p}v^2-frac {q-1}{q}v^2-frac {r-1}{r}v^2=F(x)+F(y)+F(z)+(frac 1p+frac 1q+frac 1r-1)v^2)
想要(Sleq 0)必然满足(frac 1p+frac 1q+frac 1rleq 1),构造的方法可以根据(F(x),F(y),F(z))来构造。
代码
CF835E The penguin's game
询问一个集合的异或和结果有(4)种,分别为(0,x,y,xoplus y)。
首先将所有下标依次按照每个二进制位(01)分类,询问异或和即可得到两个(y)下标的异或值。
之后再将两个下标不在一个集合的集合拿出来,再该集合内二分即可。
代码
ARC103D Distance Sums
从叶子往上推。
按(D)从大到小排序后,(D)最大的点(x)一定是叶子,根据换根的那一套理论,如果满足(y)是(x)的父亲那么就有(D_x+sz_x-(n-sz_x)=D_y),因为等式左边的量都已知,所以我们可以直接把(y)二分出来。
这样子一步步构造就好了。
值得注意的一点是,构造完一颗树后要把一个点的(D)带进去检验,因为我们只有(n-1)个等式,而变量有(n)个,我们值确定了变量之间的关系,而未确定变量的具体值。
代码
CF566E Restoring Map
首先考虑非叶子节点数目至少为(3)的情况,
两个非叶子节点(x,y)之间存在边当且仅当存在两个集合的交为({x,y}),所以我们可以知道所有非叶子节点之间的连边情况,也确定了所有叶子节点。
对于一个叶子节点,包含它且集合大小最小的点就是它自己的集合,这样我们可以确定每个叶子节点的集合。
定义连边集合为非叶子节点连向非叶子节点的边的集合,那么把每个叶子节点集合中的叶子去掉之后就是其父亲节点的连边集合,因为每个非叶子节点的连边集合不同而且上面已经确定了连边集合,所以可以确定每个叶子的父亲,这棵树也就确定了。
如果非叶子节点数目小于(3),比较容易判断,这里不再赘述。
代码
CF1053E Euler tour
考虑一个欧拉序合法的条件:
- (a_1=a_{2n-1})
- (forall a_l=a_r,l,r)同奇偶,因为其子树内每条边贡献次数均为(2)
- (forall a_{l1}=a_{r1},a_{l2}=a_{r2}),([l1,r1])有交则是包含关系
考虑如何构造,假设当前我们构造的区间为([l,r]),从左往右扫,如果发现有(a_{l'}=a_{r'}),那么递归构造([l',r']),然后删掉([l',r']),删的过程可以用链表维护。
剩下的两两肯定不能匹配,我们可以统计一下这个区间的空位置的个数,如果我们区间内空位置的个数不足以让我们匹配完全,那么就是无解,否则如果我们区间中数的种类小于(lceilfrac {r-l}2
ceil),我们就在([l,r])前面没有天的位置填上未在整个序列中出现过的数,之后再从(l
ightarrow r)考虑每个长度为(3)的区间,如果是(0xy)就变为(yxy),(xy0)就变为(xyx),然后缩点。如果区间里还有数为(0)就全部赋为这个区间的根。
正确性的话因为我们能够保证赋为根之前不会有两个(0)是相邻的所以是对的。
链表维护的复杂度为(O(n)),具体实现细节见代码。
代码