有点小难受这次打的。
DAY0
来到了北京有点小冷。
去报到的时候看到了疑似北大集训的讲题现场。
晚上颓废。
DAY1
这一天没有上百,因此我也不说具体分数是多少了。
最主要是我的心路历程。
开场看了一会儿T1没有思路。
看T2很快就会做了,写了一个小时发现过不去样例,非常难受,当时写了一个暴力发现也过不去样例,于是我去求助当时的监考,回答是no response,然而我也很智障,当时只是疯狂检查自己哪里写错了,一直找不出来,结果自闭的一批。同时头也很痛,于是干脆想着打打暴力算了。
于是就打暴力了,T3暴力就那样。
剩下的时间(也没多少时间了)就开干T1,发现数据范围是50,那肯定矩阵乘法啊,很快想出了矩阵乘法的形式,发现并不知道后续的处理,一直在想如何解决交换律之类的东西,感觉自己非常愚蠢,最后也没有想出来。
出来看别人的分数都好高啊,那我打屁啊。
zory也爆炸了,也没有上百。
出来之后pb告诉我我概率搞错了,我。。。我tm从来没想过这错了,好吧。
打完之后很难受,在校园里瞎逛了一会儿,去跟师兄们吃饭,吃得很爽。
晚上颓废。
DAY2
早上面试,全程开心聊天,觉得很爽,感觉面试可能没啥用???
中午我们跟wyt,pb,ntf一起吃饭,wyt昨天打得也是暴力,并且他跟我一样也是个二等奖,有点小难受。
下午上机之前我的心态都是随便打打的心态,毕竟我也不年轻了,翻盘感觉也翻不了多少。
进去之后花了两个小时多一点把前两题过了,有点小难受,感觉这种难度多半也翻不了盘了吧,于是抱着娱乐的心态开干T3。
T3想到了最小割树的做法,但当时不知道怎么回事儿,我以为他是O(n2logn)O(n^2\log n)O(n2logn)的,并且按照我当时的写法这非常难写,我当时脑子疼得都快炸了,实在是没法再写了,跑出去晃悠晃悠了十几二十分钟才回来。
我想这干脆写一个O(n2log2n)O(n^2\log^2n)O(n2log2n)的,一样过部分分完了。
最后也不知道干啥了,开始瞎基尔随机,然而也没什么卵用。。。
出来之后发现大家打得分数都差不多,可能差别跟昨天的差别差不多,感觉自己补回来一点?也没多想,可能又是个二等吧。
zory有点小惨,今天也打得不好。
回酒店又是颓废。
DAY3
上午没事干,非常爽快的在酒店睡觉。
叫名字是真的刺激,特别是看着二等奖一张一张派完的时候。
我跟wyt都挺惊讶的,但是就这样吧,这一等奖也不一定有啥用。
反正体验还是小难受,感觉没有打出真实水平,但也算是不错的教训了,算是积累了一些经验。
写这篇文章的时候正在备战学考呢,因此下面的题解写错了啥多多包含:
PKUWC2020题解
D1T1
我们容易发现dpdpdp是可以用矩阵来进行转移的。
我们考虑如果我们已经做完了111开头的排列,我们怎么做222开头的排列,我们容易发现这是一个变换,他相当于222号节点变成了111号节点,111号节点变成了111号节点,那么我们只需要做行和列的交换即可。
那么剩下的过程就类似于一个数位dpdpdp。
D1T2
可以考虑计算一个集合的贡献。
考虑这个概率是什么东西,我们可以发现,一个大小的集合出现的概率之和它的大小和分成多少个集合有关,那么我们考虑计算出fif_ifi为大小为iii的集合的贡献之和。
这个东西的计算是平凡的,我们可以考虑把式子拆成max2−2maxmin+min2\max^2-2\max\min+\min^2max2−2maxmin+min2来算,这些东西大概都是可以用卷积来优化的。
我们考虑设g(i,k)g(i,k)g(i,k)为大小为iii的集合,合成了kkk次的出现的概率。
则容易发现这其实是一个组合数的过程:
式子大概就是你按照题目的定义写出一堆(n2){n\choose 2}(2n)相乘的结果,假设一共有nnn个数:
g(s,k)=∏i=2s(i2)∏i=n−k+1n−s(i2)(ks−1)∏i=2n(i2)=s!(s−1)!(n−s)!(n−s−1)!(n−k)!(n−k−1)!k!(s−1)!(k−s+1)!n!(n−1)!=s!(n−s)!(n−s−1)!(n−k)!(n−k−1)!k!(k−s+1)!n!(n−1)!
\begin{aligned}g(s,k)&=\frac {\prod_{i=2}^s{i\choose 2}\prod_{i=n-k+1}^{n-s}{i\choose 2}{k\choose s-1}}{\prod_{i=2}^n{i\choose 2}}\\&=\frac {s!(s-1)!\frac {(n-s)!(n-s-1)!}{(n-k)!(n-k-1)!}\frac {k!}{(s-1)!(k-s+1)!}}{n!(n-1)!}\\&=\frac {s!\frac {(n-s)!(n-s-1)!}{(n-k)!(n-k-1)!}\frac {k!}{(k-s+1)!}}{n!(n-1)!}\end{aligned}
g(s,k)=∏i=2n(2i)∏i=2s(2i)∏i=n−k+1n−s(2i)(s−1k)=n!(n−1)!s!(s−1)!(n−k)!(n−k−1)!(n−s)!(n−s−1)!(s−1)!(k−s+1)!k!=n!(n−1)!s!(n−k)!(n−k−1)!(n−s)!(n−s−1)!(k−s+1)!k!
大概是这样,我也不知道对不对。
那么我们考虑答案是让你计算h(i)h(i)h(i)表示合成了n−i+1n-i+1n−i+1次的结果。
那么:
h(k)=∑i=1nfig(i,n−k+1)
\begin{aligned}h(k)&=\sum_{i=1}^{^n}f_ig(i,n-k+1)\\\end{aligned}
h(k)=i=1∑nfig(i,n−k+1)
你如果把上面的那些东西照搬下来你可以发现可以写出之和kkk相关的,之和iii相关的,之和i−ki-ki−k相关的,因此可以卷积。
D1T3
我们考虑把答案的贡献式写出来,设当前询问是l,r,xl,r,xl,r,x,设ppi=max(0,min(ri,r)−max(li,l)+1)pp_i=\max(0,\min(r_i,r)-\max(l_i,l)+1)ppi=max(0,min(ri,r)−max(li,l)+1),
假设一个修改是li,ri,xi,vil_i,r_i,x_i,v_ili,ri,xi,vi这样的:
ans=∑i=1qppivi∑j=1n[gcd(x,j)=1][gcd(xi,j)=1]=∑i=1qppivi∑j=1n∑d1∣x,d1∣jμ(d1)∑d2∣xi,d2∣jμ(d2)=∑i=1qppivi∑d1∣xμ(d1)∑d2∣xiμ(d2)nlcm(d1,d2)
\begin{aligned}ans&=\sum_{i=1}^qpp_iv_i\sum_{j=1}^n[\gcd(x,j)=1][\gcd(x_i,j)=1]\\&=\sum_{i=1}^qpp_iv_i\sum_{j=1}^n\sum_{d_1|x,d_1|j}\mu(d_1)\sum_{d_2|x_i,d_2|j}\mu(d_2)\\&=\sum_{i=1}^qpp_iv_i\sum_{d_1|x}\mu(d_1)\sum_{d_2|x_i}\mu(d_2)\frac {n}{\mathrm{lcm}(d_1,d_2)}\\\end{aligned}
ans=i=1∑qppivij=1∑n[gcd(x,j)=1][gcd(xi,j)=1]=i=1∑qppivij=1∑nd1∣x,d1∣j∑μ(d1)d2∣xi,d2∣j∑μ(d2)=i=1∑qppivid1∣x∑μ(d1)d2∣xi∑μ(d2)lcm(d1,d2)n
考虑枚举D=gcd(d1,d2)D=\gcd(d_1,d_2)D=gcd(d1,d2),那么,我们令CdC_dCd表示修改中满足d∣xd|xd∣x的式子,令QdQ_dQd为询问中满足的式子,设:
ol(l1,r1,l2,r2)=max(0,min(r1,r2)−max(l1,l2)+1)ol(l_1,r_1,l_2,r_2)=\max(0,\min(r_1,r_2)-\max(l_1,l_2)+1)ol(l1,r1,l2,r2)=max(0,min(r1,r2)−max(l1,l2)+1),则:
ans=∑D=1n∑d1=1⌊nD⌋μ(d1D)∑d2=1⌊nD⌋μ(d2D)[gcd(d1,d2)=1]⌊nd1Dd2D⌋∑i∈Cd1D∑j∈Ad2Dol(li,ri,lj,rj)xi=∑D=1n∑d1=1⌊nD⌋μ(d1D)∑d2=1⌊nD⌋μ(d2D)∑d∣d1,d∣d2μ(d)⌊nd1Dd2D⌋∑i∈Cd1D∑j∈Ad2Dol(li,ri,lj,rj)xi
\begin{aligned}ans&=\sum_{D=1}^n\sum_{d_1=1}^{\lfloor\frac nD\rfloor}\mu(d_1D)\sum_{d_2=1}^{\lfloor\frac nD\rfloor}\mu(d_2D)[\gcd(d_1,d_2)=1]\lfloor\frac n{d_1Dd_2D}\rfloor\sum_{i\in C_{d_1D}}\sum_{j\in A_{d_2D}}ol(l_i,r_i,l_j,r_j)x_i\\&=\sum_{D=1}^n\sum_{d_1=1}^{\lfloor\frac nD\rfloor}\mu(d_1D)\sum_{d_2=1}^{\lfloor\frac nD\rfloor}\mu(d_2D)\sum_{d|d_1,d|d_2}\mu(d)\lfloor\frac n{d_1Dd_2D}\rfloor\sum_{i\in C_{d_1D}}\sum_{j\in A_{d_2D}}ol(l_i,r_i,l_j,r_j)x_i\\\end{aligned}
ans=D=1∑nd1=1∑⌊Dn⌋μ(d1D)d2=1∑⌊Dn⌋μ(d2D)[gcd(d1,d2)=1]⌊d1Dd2Dn⌋i∈Cd1D∑j∈Ad2D∑ol(li,ri,lj,rj)xi=D=1∑nd1=1∑⌊Dn⌋μ(d1D)d2=1∑⌊Dn⌋μ(d2D)d∣d1,d∣d2∑μ(d)⌊d1Dd2Dn⌋i∈Cd1D∑j∈Ad2D∑ol(li,ri,lj,rj)xi
我们考虑枚举DdDdDd:
ans=∑D=1n∑d∣Dμ(d)∑d1=1⌊nD⌋μ(d1D)∑d2=1⌊nD⌋μ(d2D)⌊nd1d2Dd⌋∑i∈Cd1D∑j∈Ad2Dol(li,ri,lj,rj)xi
\begin{aligned}ans&=\sum_{D=1}^n\sum_{d|D}\mu(d)\sum_{d_1=1}^{\lfloor\frac nD\rfloor}\mu(d_1D)\sum_{d_2=1}^{\lfloor\frac nD\rfloor}\mu(d_2D)\lfloor\frac n{d_1d_2Dd}\rfloor\sum_{i\in C_{d_1D}}\sum_{j\in A_{d_2D}}ol(l_i,r_i,l_j,r_j)x_i\end{aligned}
ans=D=1∑nd∣D∑μ(d)d1=1∑⌊Dn⌋μ(d1D)d2=1∑⌊Dn⌋μ(d2D)⌊d1d2Ddn⌋i∈Cd1D∑j∈Ad2D∑ol(li,ri,lj,rj)xi
则我们最外层枚举一个DDD,然后考虑对于每个DDD单独做:
则先考虑修改,我们考虑这样子做,对于枚举D,d,d1D,d,d_1D,d,d1,我们把⌊nd1dD⌋\lfloor \frac n{d_1dD}\rfloor⌊d1dDn⌋这一行区间加,那么我们考虑复杂度计算:
∑D=1n∑d∣D∑d1=1⌊nD⌋nd1D=∑D=1n∑d∣DnDlogn=∑d=1n∑D=1⌊nd⌋nDdlogn=∑d=1nndlog2n=nlog3n
\begin{aligned}&\sum_{D=1}^n\sum_{d|D}\sum_{d_1=1}^{\lfloor\frac nD\rfloor}\frac n{d_1D}=\sum_{D=1}^n\sum_{d|D}\frac nD\log n\\=&\sum_{d=1}^n\sum_{D=1}^{\lfloor\frac nd\rfloor}\frac n{Dd}\log n=\sum_{d=1}^n\frac nd\log^2n\\=&n\log^3n\end{aligned}
==D=1∑nd∣D∑d1=1∑⌊Dn⌋d1Dn=D=1∑nd∣D∑Dnlognd=1∑nD=1∑⌊dn⌋Ddnlogn=d=1∑ndnlog2nnlog3n
我们考虑这个东西我们做一个前缀和,但在那之前我们可以离散化一波,容易发现,我们只有CD,QDC_D,Q_DCD,QD中的列是有用的,而这个东西的大小大概是O(nD)O(\frac nD)O(Dn)的,行的数量大概是nD\frac nDDn那么我们预处理的复杂度就是:
∑D=1nnDlogn=O(nlog2n)
\sum_{D=1}^n\frac nD\log n=O(n\log^2n)
D=1∑nDnlogn=O(nlog2n)
做一遍二维前缀和复杂度为:
∑D=1n(nD)1.5≈n1.5∫0n(1t)1.5dt=O(nn)
\sum_{D=1}^n(\frac nD)^{1.5}\approx n^{1.5}\int_0^n(\frac 1t)^{1.5}dt=O(n\sqrt n)
D=1∑n(Dn)1.5≈n1.5∫0n(t1)1.5dt=O(nn)
然后你枚举d,D,d2d,D,d_2d,D,d2,然而这里跟上面不太一样的是我们还要枚举一个行,我们注意到第iii行的贡献是⌊id2⌋\lfloor\frac i{d_2}\rfloor⌊d2i⌋,则我们可以考虑枚举⌊id2⌋\lfloor \frac i{d_2}\rfloor⌊d2i⌋,由于iii是⌊nd1Dd⌋\lfloor\frac n{d_1Dd}\rfloor⌊d1Ddn⌋这样的形式,于是肯定可以写成:⌊nDd1⌋x\frac {\lfloor \frac n{Dd_1}\rfloor}{x}x⌊Dd1n⌋的形式,于是只有O(⌊nDd1⌋)O(\sqrt {\lfloor\frac n{Dd_1}\rfloor})O(⌊Dd1n⌋)段,那么每一段都是一个矩阵和,由于此时已经不含ddd了,则复杂度是:
∑D=1n∑d1=1⌊nD⌋(nd1D)1.5≈n1.5∑D=1n(1D)1.5≈n1.5
\sum_{D=1}^n\sum_{d_1=1}^{\lfloor \frac nD\rfloor}(\frac n{d_1D})^{1.5}\approx n^{1.5}\sum_{D=1}^n(\frac 1D)^{1.5}\approx n^{1.5}
D=1∑nd1=1∑⌊Dn⌋(d1Dn)1.5≈n1.5D=1∑n(D1)1.5≈n1.5
至此问题在O(nlog3n+nn)O(n\log^3n+n\sqrt n)O(nlog3n+nn)的时间内解决。
D2T1
我们考虑维护一个A,B,SA,B,SA,B,S表示前面有AAA个毒鱼没有使用,有SSS对配对的小于和毒鱼,有BBB个小鱼还剩下,那么做一个前缀和就完事了,剩下的部分是简单贪心。
D2T2
我们考虑笛卡尔树维护,我们把询问挂在区间最大值上面,那么我们需要维护两个线段树,一个线段树表示左端点到某个节点的值,一个线段树表示右端点到某个节点的值,那么我们需要一个区间乘法就完了。
D2T3
考虑最小割树,最小割树的过程大概就是做O(n)O(n)O(n)次网络流就把图建出来,过程如下:
一开始找到两个点u,vu,vu,v,设他们之间的最小割为cut(u,v)cut(u,v)cut(u,v),我们把属于uuu的放在一起设为UUU,属于vvv的放在一起,设为VVV,则有引理对于任意x∈U,y∈Vx\in U,y\in Vx∈U,y∈V满足cut(x,y)≤cut(u,v)cut(x,y)\le cut(u,v)cut(x,y)≤cut(u,v)。
反证:假设有cut(x,y)>cut(u,v)cut(x,y)>cut(u,v)cut(x,y)>cut(u,v)那么就不能把u,vu,vu,v割开,因为x,yx,yx,y相连。
那么我们分成集合UUU和集合VVV递归去做,这样子最后就建成了一个树形结构,两点之间的最小割就是两点路径上的最小值。
那么有了这个东西,现在题目的要求相当于变成了,让你O(n)O(n)O(n)求最小割。
我们考虑断开两条边的贡献,那么断开后形成的两个集合之间必须没有边相连,那么每条边实际上就可以贡献O(1)O(1)O(1)个矩阵,做一个二维前缀和就可以算出断开两条边的贡献。
那么我们观察两个点之间可用的边对是哪些,容易发现他长成这样:

做一个行的前缀min\minmin,列的后缀min\minmin,然后暴力枚举行或列即可。
那么时间复杂度是O(n2)O(n^2)O(n2),据说可以更快变成O(nnlogn)O(n\sqrt n\log n)O(nnlogn)。

本文回顾了作者参加PKUWC2020竞赛的经历,包括比赛的心路历程、每日状态及最终成绩感受。并详细解析了竞赛题目,包括DP、概率计算、最小割树等算法题的解题思路与实现细节。
3322

被折叠的 条评论
为什么被折叠?



