NOIP前做题记录

鉴于某些原因(主要是懒)就不一题一题写了,代码直接去(OJ)上看吧

CodeChef Making Change

传送门

完全没看懂题解在讲什么(一定是因为题解公式打崩的原因才不是曲明英语太差呢……)

由于(C=sum x_i imes a_i),我们可以把(x_i)给二进制分解,然后依次考虑每一位

(f_{i,j})表示考虑到(C)的二进制第(i)位,且(0)(i-1)位都已经对上,进位为(j)的方案数,那么考虑所有(x_i)当前这一位,每一个(a_i)最多选一个,用一个类似背包的东西计算出(g_j)表示总共进位为(j)的方案数,转移就是(f_{i+1,j}+=g_{2j+c_{i+1}}),其中(c_{i})表示(c)的二进制第(i)

时间复杂度(O(能过))

wannfly挑战赛24E

传送门

直接离线点分+背包,记得询问得挂到点分树的(LCA)

wannfly挑战赛24F

传送门

发现这个柿子长得很像递推数列的通项公式,那么我们相当于已经知道了特征方程的所有解,直接分治(NTT)求出原来的特征方程,然后带进去暴力递推出第(n)项就行了

51nod1599

传送门

生成函数神仙题,看题解吧

51nod 1309

传送门

发现一个数有贡献当且仅当它排在所有比(m)大的数的前面,记总共有(k)个,由于它和这(k)个数全都不同,所以它在这些数前面的概率是({1over k}),记所有小于等于(m)的数总和为(s),本质不同的排列个数为(p),则答案为({psover k})

51nod 1653

传送门

类似赌徒破产问题,把两个过程的转移写出来,可以得到两个同构的通项公式,记(p_i)为收益为(i)时获胜的概率,则(p_i=f_i(-wleq ileq a+1),p_i=g_i(aleq ileq s)),那么两个通项公式总共四个未知数,根据四个边界条件(f_{-w}=0,g_{s}=1,f_{a}=g_a,f_{a+1}=g_{a+1}),高斯削元或者直接手动解出未知数再带进去就行了

51nod 1253

传送门

转化为计算不符合条件的,那么在只考虑黑边的情况下至少有两个点在同一连通块里,算一下就行了

51nod 1251

传送门

枚举出现次数最多的出现次数(k),那么剩下的全部都得小于(k),容斥然后枚举大于等于(k)的个数(j),这(j)个先强行选(k),剩下的随便选就行了。选的方案数可以差分之后用隔板法求

51nod 1317

传送门

发现如果合法一定存在(C)满足(|C|<|A|),又因为(A+C=C+B),则可得(A=C+D,B=D+C),那么只要考虑拆分(A)(C,D)的方案数即可,发现对于某个(A),如果将其拆分为(C_1=A[1,p],D_1=A[p+1,n])(C_2=[1,q],D_2=[q+1,n])(C_1+D_1=C_2+D_2),当且仅当(L=q-p)(A)的最小循环节的长度,那么此时拆分(A)的方案就是(L),记长为(i)且最小循环节长度为(i)的串个数为(f_{i}),因为(n)的因子个数不多,所以暴力找出所有的因子然后容斥+dp计算(f_{i})即可

51nod 1375

传送门

(c_i)表示有因子(i)的数的个数,那么用(mu)容斥一下就行了

51nod 1407

传送门

同上,根据二进制个数(1)的奇偶性容斥即可

51nod 1149

传送门

考虑这个柿子的含义,相当于从(n)出发,每次往左走(1)步或者(pi)步,求走到([0,4))的方案数,那么我们枚举一下总共走了多少个(1),同时要记得判断一下此时(1)能够放在最后一步走

51nod 1404

传送门

发现(n,m)可以分开考虑,对于单独的(n)相当于令(s=n-1-2k),对于每一个(sum_{i=1}^k p_ileq s)(p)贡献是(prod_{i=1}^k (p_i+1)),考虑组合意义后面的乘积就相当于是求(0leq a_ileq p_i)(a)的个数,那么可以把(a)和上面的空格分开枚举,最后颓柿子得到方案数为({n-1choose 2k}),分段打表预处理阶乘+卢卡斯定理,顺便注意如果(k>2^{63}-1)那么(*2)之后会爆unsigned long long,记得特判

51nod 1843

传送门

如果已经确定了(A,B),那么就是这里第一场的(D)题了

这里也类似考虑,设(f_{i,j,k})表示考虑完了(A[1,..,i],B[1,..,j]),且其中相同的元素个数为(k)的方案数,转移如下

[egin{aligned} f_{i+1,j,k}+=f_{i,j,k} imes (n-i-j+k)\ f_{i,j+1,k}+=f_{i,j,k} imes (n-i-j+k)\ f_{i+1,j,k+1}+=f_{i,j,k} imes (j-k)\ f_{i,j+1,k+1}+=f_{i,j,k} imes (i-k)\ end{aligned} ]

其中第一个柿子意思是在(A)的下一个放一个没有在(A,B)中出现过的数,第二个柿子同理,第三个柿子意思是在(A)的下一个放一个在(B)中出现过的数,第四个柿子同理

然后去重

[egin{aligned} f_{i,j,k}-=sum_{d=1}^k {n-(i-d+j-d-k+d)choose d}f_{i-d,j-d,k-d} imes g_d imes d! end{aligned} ]

等价于枚举前面有多少是重的,注意那个组合数不能写成({kchoose d})

ps:有些模数的情况下会有dp中间量为(0),所以注意只枚举那些合法的(i,j,k)(即(max(0,n-i-j)leq kleq min(i,j))

51nod 1260

传送门

我对生成函数一无所知……

首先对于计数,我们把树上所有非叶节点染色,若为白就不交换左右儿子,为黑就交换,这样肯定可以枚举所有情况。为了避免重复,我们规定每个点和它的左儿子颜色不能相同(否则可以把这个点和它的左儿子splay操作之后得到另一棵树,且这两棵树等价),那么这样就可以不重不漏的统计所有答案

发现除了左儿子是叶子的,其它点的颜色都已经确定了(必须与左儿子颜色相反),然后把所有的叶子都去掉,那么只有那些没有左儿子的可以随便选

(h_n)为树上总共(n)个点时的答案,则有

[egin{aligned} h_n=sum_{i=1}^n h_ih_{n-1-i}+2h_{n-1}=sum_{i=0}^n h_ih_{n-1-i}+h_{n-1} end{aligned} ]

就是枚举根节点左儿子的点的个数,同时如果没有左儿子则根节点颜色任意

考虑生成函数,有

[egin{aligned} H(x)=(H^2(x)+H(x))x+1\ H(x)={1-xpm sqrt{x^2-6x+1}over 2x} end{aligned} ]

因为当(x o 0)(H(x) o 1),所以应该取负号,即

[egin{aligned} H(x)={1-x- sqrt{x^2-6x+1}over 2x} end{aligned} ]

多项式快速幂即可

或者快速计算,先特判(n=1),之后我们要计算的是(h_{n-1}),也就是(-{1over 2})乘上((x^2-6x+1)^{1over 2})的第(n)项,对于这个东西直接暴力二项式展开

[egin{aligned} left(x^2-6x+1 ight)^{frac 1 2}=sum_{i=0}^{infty}(x^2-6x)^icdot inom{frac 1 2}{i} end{aligned} ]

考虑第(x^n)项的系数,枚举有(i)(x^2)的贡献,则(-6x)的贡献就是(n-2i)次,所以这一项就是((x^2-6i)^{n-i}),对答案的贡献为

[egin{aligned} (-6)^{n-2i} imes inom{frac 1 2}{n-i} imes inom{n-i}{i} end{aligned} ]

所以答案即为

[egin{aligned} ans=-frac 1 2sum_{i=0}^{leftlfloorfrac n 2 ight floor}(-6)^{n-2i} imes inom{frac 1 2}{n-i} imes inom{n-i}{i} end{aligned} ]

对于那个奇怪的组合数,有({{1over 2}choose k}={({1over 2})^{underline{k}}over k!}),暴力预处理就行了

It's a Mod, Mod, Mod, Mod World

传送门

类欧板子

KM and M

传送门

按位考虑,第(k)位的贡献就是(sum_{i=1}^n immod 2^{k+1}-sum_{i=1}^n immod 2^k),类欧算一下就行了

F - Probe Droids

传送门

(Stern-Brocot Tree)上二分,然后转化为直线下整点问题,用类欧求解

不过如果在(SBT)上直接二分次数会达到(O(n)),所以我们只需要二分拐点,这样次数就是(O(log n))的了,单次询问复杂度(O(log^3 n))

BZOJ 4977

传送门

模拟费用流,如果贪心匹配兔子(a)和洞(b)的贡献是(x_a+v_b),其中(v_b=-x_b+w_b),但是有可能之后某一个兔子(c)去和(b)匹配更优,那么当做多了一个代价为(-x_a)的洞即可,从左往右用堆维护

UOJ455

传送门

模拟费用流,注意每只兔子先匹配一个代价(infty)的洞,然后对于兔子考虑它被别的洞抢,对于洞考虑它抢了别的兔子,被别的兔子抢的情况就行了

因为有多个所以额外记个数量,拆点复杂度不会证

CEOI2019 Dynamic Diameter

传送门

LCT,由于每个点在的splay代表的是一条链,记当前splay中深度最浅的节点为(p),每个点上维护(lmx)表示splay中深度最浅的节点到在(p)的子树中的节点的最远距离,(rmx)表示深度最深的节点到(p)的子树中的最远距离,(mx)表示子树内经过当前节点的最长链的距离,每个点再开一个可删堆维护所有虚子树中的最长链(不难发现对于虚子树,最长链就是它们的(lmx)),再全局开一个堆维护所有的(mx),一次修改只需要把对应的节点(access)再splay之后直接改掉就行了,并不会产生我之前担心的“改掉某个点之后它父亲记录的虚子树的最长链出问题”(因为这个的变化只会在更改点权的时候,其他情况下splay来splay去都不会变的,而更改点权的时候我们已经保证它没有父亲了)

不是很难写,但鉴于我手写可删堆挂了+不会背LCT的板+yy的时候出了问题,人就没了

CEOI2019 Amusement Park

传送门

曲明是个sb,第一步都没想出来

我们考虑看成是无向图无环定向,发现每一种方案都可以对应到另一种每条边方向相反的合法情况,且这两个加起来权值总和为(m),那么计算无环定向数方案乘上(m/2)就行了。不会jz姐姐说的色多项式只好用子集卷积艹过去(不会子集卷积求无环定向数的看这里的F)

CEOI2019 Magic Tree

传送门

(f[i][j])表示考虑(i)的子树,第(j)天的最大值,转移就是把子树加起来并对一个后缀取(max),写了个线段树合并结果(RE)

所以看了jz姐姐的做法,是用一个对于一个(f_i)用一个(map)维护它的差分数组,这样只需要记录那些差分不为(0)的位置,一次后缀取(max)操作只要找到对应的位置,把差分数组改一改就行了,(map)的合并用启发式合并就行了

LOJ6405

传送门

树上模拟费用流,用可并堆把子树里的堆给合并起来就行了

bzoj4140

传送门

某个点(x,y)在圆((a,b))内的条件是((x-a)^2+(y-b)^2leq a^2+b^2),化简之后就是(2ax+2bygeq x^2+y^2),右边是个定值,左边可以看成是((a,b))((x,y))两个向量的点积,那么我们只要求这个点积的最小值就行了,据说点积的最值必定在凸壳上出现且是个单峰函数,那么(y>0)在下凸壳三分,否则在上凸壳三分即可。对于强制在线维护凸壳,我们二进制分组即可,具体就是每次重构末尾(lowbit)位的凸包,这样点被处理的总次数是(O(nlog n))的,复杂度为(O(nlog^2n))

PE619

传送门

对于每一个数,记(n=pi(r))表示(leq r)的素数个数,那么把每个数(x)当成一个二进制的(n)位向量,其中第(i)位为(1)当且仅当(x)中第(i)个素数的次数是奇数,那么问题等价于有多少个非空子集异或和为(0),用线性基可以证明答案就是(2^{非*元个数}-1),所以维护一下线性基就好了,注意由于线性基里元素不会很多,所以这里的线性基可以用(vector)来维护,每次找到最开头的(1)就行了

然而由于询问的区间非常大,所以直接把区间里所有有倍数出现过的质数的个数当成线性基里基的个数就可以过了

PE548

不难发现(g_n=sum_{d|n,d<n}g_d),而且(g)实际上只和(n)的质因子的次数的集合有关,那么我们对于每个用尽量小的质因子来表示,爆搜出所有的合法的集合(大概(17000)个),然后对于每个爆搜因子来算出对应的(g)是多少(所有因子个数加起来大概(10^9)个),然后再对于每个(g)暴力分解质因子判断(g_n=n)是否成立即可