2024寒假集训记录

1|02024.1.12

这次比赛结果不错,rank1,195pts,但还有提升空间

1|1T1

赛时对着性质打,没想正解
其实可以简单树剖做到95
正解:考虑把路径拆成向上的一段和向下的一段,设起点为s,终点为t
那么向上的一段的一个点P被贡献的条件是dep[s]==dep[P]+w[P],向下的一段的一个点P被贡献的条件是dis(s,t)w[P]=dep[t]dep[P],移项得dis(s,t)dep[t]=w[P]dep[P],对于每一个点开一颗动态开点权值线段树,从子树中合并信息然后直接查即可

1|2T2

赛时打的堆
首先,把分出来的分成两类,即px和另一个,q等于0的情况,每次分出来的有单调性,可以用三个队列处理
对于q>0的,目标是证明,px+q>=(p(y+q)),其中x>=y,由于px+q=px+q,(p(y+q))=(py+pq),p<=1,所以一定是满足的,另一种一样证明即可,然后就可以用上面的三个队列处理了

1|3T3

其实是一道简单题
发现每个区间的放置情况最多堆答案产生1的影响,而且前面的Ai×x+pj<=i(apj+X)越大,后面的填就越自由,所以如果这个区间不产生1的贡献,就把区间的数全部选上,如果产生,由于要每个位保证上面的式子大于0,就可以打一个反悔贪心,如果当前位置不合法,就前面找一个最大的使它变合法,这样显然是对的,那么就设f[i][j]表示到了第i个区间,选了j个的最大的上面的式子是多少,然后就可以转移了,时间复杂度O(nm2log)

1|4T4

一道不错的题,很有难度
先考虑链的情况,先分块,对于一个中间的数,考虑两边,如果三个数都在一个块,枚举两个数,用桶记录第三个
预处理出两边的桶,如果两个在一个块,就在所在的那边查
如果只有一个在,把两边的桶卷积,然后查即可,这个复杂度看起来能过
然后考虑树的情况,那么延续上面的想法,对于树分块
分块的方法也很简单,用一遍树形dp,如果儿子中有离这个点距离超过B的,就把这个点设为关键点,把一个关键点和它的祖先关键点设为同一块,虽然块之间可能有重复,但不影响
我们转而维护最后一个数,因为如果要维护子树,这种方式不利于维护
然后开始分类讨论,x,y,z分别为题目中的三个点
1,y,z在同一块,对于上面的维护每个值出现次数的桶
2,x,y在同一块,对于上面的块维护出这个即可,这个也好算,枚举两个数更新到桶里
3,都不在一个块,还是维护一个桶
每次更新,上面的两种就直接更新,下面的就卷一下,介绍一下减法卷积:
正常的卷积就是f(i)×g(j)=h(i+j),变换一下,f(i)×g(Vj)=h(i+Vj),然后就可以做了,而g的操作就是反转整个g,然后就可以直接求解
因为一些奇怪的细节+大常数只拿了90

2|02024.1.13

3|02024.1.15

这次比赛一般,分数忘了,排名rank6

3|1T1

打表or(推性质)+找规律题
首先,用一个较快的暴力算出8×8的,然后再算出8×9的,就可以发现,ans(n,m)=ans(m,n),ans(n,m)=3×ans(n,m1)(m>n+1),就可以直接递推了

3|2T2

模板题
赛时从头推了一遍ddp,然后就花费了3h,还因为细节只有60
首先把转移写出,f[x][0/1]就是当前不选/选,然后根据题意写方程,然后把树剖了
g[x][0/1]表示不考虑重链的答案,可以最开始求f的时候顺便求出
然后定义一种矩阵乘法:a[i][j]=min(b[i][k]+c[k][j]),感性理解,满足结合律
这种样子的一般都满足(如果不是当我没说)
那么把矩阵写成这种形式:
[g[i][1]g[i][1]g[i][0]inf]×[f[hs][1]f[hs][0]]=[f[i][1]f[i][0]]
就是对的
求一个点的答案,就是当前点到当前点所在重链底部的矩阵的乘积,因为叶子的g就是f(没有儿子)
那么修改就是对于一个点的g修改,然后看这条重链的改动量,改到链头的fa,这样不断向根跳
然后直接把1所在的重链的矩阵乘起来(线段树)输出即可

3|3T3

先把被包含的去掉,K也相应的减
首先有一个简单的dp:
f[i][j]表示到第i个区间(必须选i),放弃了j个的最大代价
f[i][j]=min(f[k][jlen(i,k)]+R[i]max(L[i],R[k])),直接转移是O(nk2)的,似乎可以过?
正解:把里面的式子拆开,jlen(i,k)=j(ik1)=k(ij1),len要-1是因为两边都选,就中间的不选
把区间按左端点从小到大排序,由于被包含的已经被去掉了,右端点也是从小到大的
然后我们对比上面式子的第一维减第二维的值,发现左边的是ij,右边的是ij1,也就是前一个
我们设ij1=now,我们就可以对于每个now开一个单调队列,然后顺序枚举i,j,这样转移就是对的,因为出队列的就不会再进队列
至于维护单调队列,把上面的式子拆开,就可以分两部分统计了,而且是连续的,可以用双指针来搞一下,然后更新now+1的单调队列
最后统计答案,就在最后加上一个长度为0的区间,然后就钦定它必须选,然后就可以按上面的转移来统计答案,输出f[n][k]即可,n为加上最后一个区间的总共区间个数
空间看起来是O(n2)的,但发现只会有n×k个元素进队列,用上deque就是对的(vector也可以)

3|4T4

首先,被包含的区间一定呈阶梯状,类似
...xx
..xx.
.xxx.
.xx...
发现,对于一行,它的区间左端就是这一行上面或这一行的喷头的纵坐标最小值,右端就是下面的(包括这行)喷头的纵坐标最大值
我们发现每一行是不断左移的,就可以根据这个性质和l,r处理出up(当前列最上端的行)
那么答案就可以写成i=1nj=lirip=lij1q=uppi11,推一下式子,
=i=1nj=lirip=lij1(iupp)=i=1n(j=lirip=lij1ij=lirip=lij1upp)
我们对于两部分化简
左边的:
=j=lirii(jli)=ij=liri(jli)=i(j=lirij(rili+1)×li)=i((li+ri)×(li+ri+1)2((rili+1)×li))
右边的:
sum0i为up的前缀和,sum1i为sum0的前缀和
那么右边的就可以表示成:
=j=liri(sum0j1sum0li1)=j=lirisum0j1j=lirisum0li1=(sum1ri1sum1li2)+(rili+1)×sum0li1
就可以直接O(n)算了

下午:
你说的对,但是:
1717:00
感觉是巧合?我的noip巨低,但报上了,很多noip比我高的都没报上?
珍惜机会,这十天好好提升自己,争取不降智,不丢自己,学校的脸
upd:似乎破案了,按csp排的,因为noip本来就不是正式参赛的,但也是压线过的,很险

4|02024.1.16

这次G了,而且有巨大巧合,我就出去上了5min厕所,结果直接完美错过更新大样例的信息,导致我根本不知道大样例
导致唯一没打对拍的T2 G了,只有210pts,身败名裂

4|1T1

分三部分,考虑根据400循环的性质随便搞搞即可

4|2T2

先把所有数或上,然后看哪些位有限制,没有限制的直接随便选,方案好算,然后就减去输入的个数即可
注意开int128,因为264会超过ull的限制

4|3T3

赛时还好没直接打暴力,想出了正解
感觉讲的很不清楚
首先,还是那个例子,((x+y)z+c)w=xzw+yzw+cw,也就是说,加一个数对于最终答案的贡献就是加上这个数后面的全局乘的乘积再乘这个数,就启发我们考虑从后往前做
假设已经做到了第i个操作,已经求出了后面的全局乘的乘积为X
那么,后面对于这个操作中的每一个加的贡献就为X,直接考虑继续倒着,对于这个操作也倒着,同时记录当前操作从后到前的贡献(全局乘),这个也可以直接算
但是一个操作的叶子节点(加,乘)的个数是O(n)的,我们可以联想到懒标记(标记永久化?),每次把信息记录到当前点,然后最后再把信息传给子树
怎么记录呢?就在这个节点加上X即可,因为ax+ay=a(x+y),而这个节点往后的操作是固定的,所以可以直接加,对于操作内部,可以后面再处理
那么我们操作完后,从根往叶子dfs,每次加上当前节点的lazytag,然后乘上操作内部贡献(操作内部对于任意位置的当前节点操作的贡献都是一定的),这样到叶子,如果是加,就对于那一位加上到根的链和加的数所造成的贡献
上面的是树的解法,对于正常图,直接跑拓扑排序然后对于后继节点像上面一样加上当前节点的贡献即可
最后加上初始值的贡献
建议自己算一下贡献

4|4T4

假设当前的最大蛇为X,最小为Y
如果X吃了Y不会变成最小蛇,那么次大的如果吃,就一定会比X死的更早,那么就可以把问题交给下一条蛇
如果会,那么看下一条最大蛇的抉择,这样递归,如果有一条蛇吃了后不会最小,就一定会吃,那么它的上一个一定不会吃(因为这样会被吃),然后再上一个就可以放心吃(因为不会被吃),这样回推到第一条吃了会最小的蛇就可以了,如果它吃,那么答案会-1
用双端队列模拟这个过程,还没写
upd:对着题解写完了,感觉代码实现能力太差了

5|02024.1.17

这次又G,挂了64pts,不挂就rank1了
rank7
似乎有人看过/做过原题?反正我没做过

5|1T1

发现是DAG,拓扑一下即可
出题人要输出分数,然后就要int128了,挂了40

5|2T2

赛时:想了很久无果,打暴力,结果发现n(1/1+1/2+1/3...)是log级别的,就打了一个根号,期望84
结果,数组没清完,挂了24
正解:
先用Z函数求出每个位置为起点的后缀和整个串的lcp
然后枚举循环节长度,设为i,然后看Z[i+1]的值,那么循环的次数就为:
Z[i+1]i+1,加上开始的那一个串
然后考虑另一个限制,发现如果多循环两次,实质是一样的,所以可以分两部分考虑
1,循环次数为奇数
那么就直接看第一个出现的的答案乘上奇数的个数即可,即求f(1,j)<=f(i,n)的j的个数,这个j可以枚举时加到树状数组中,同时对于每个位置动态的维护到头的f和到尾部的f即可
2,循环次数为偶数
那么C的F和整个的F是一样的,也比较好算,即f(1,j)<=f(1,n),这个也可以树状数组查,然后就做完了

5|3T3

有一种极其神妙的做法
我们考虑每次满足一列,这样问题就被转化成了小1的子问题
我们假设现在做到了i,i+2n+1满足了条件,i+1为空
这里为了方便,设p[i]表示这一列实际上是哪一列,也就是第i列的柱子最开始是哪一列,发现柱子的编号是可以随便换的,不影响,所以更换两个柱子的位置(不是操作,只是重新标号)就可以只交换p了
那么下面的操作也是在p的意义下
我们的目标就是把i+1柱子上全部堆上颜色为i的球

1|0Step 1:

首先,我们把目标拆分,考虑把i柱子全部堆上颜色不为i的球,为了方便把颜色重标号,为i的就是1,不为i的就是0
考虑先把第一列的1的个数求出,设为tot,然后把第i列的tot个球移到第i+1列
这一步其实是为了给第一列的1腾位置,然后把第一列的0全部移到i+1,1全部移到i,然后再把移过去的0全部移回来
然后第二列把0放到第一列,把1或多出来的0放到i+1列,这样第二列就是空的,第一列就是全0的,然后交换一下p即可
至于为什么可以呢?首先,1的个数总共为m,那么前两列的1的个数<=m,那么0的个数就>=m,那么就可以填满一列

1|0Step 2:

然后继续构造,做Step1的前两步,即把第一列清空,把1和0转移到i,i+1,结果我们发现,i+1形成了一个新的0列(i列全0,1只会把0转移到i),i变成了一些1在上面,0在下面的情况,而1被清空了
这样,继续换一下p,然后不断这样做,就变成了一列i0,一列i+1空,剩下的1全在上面,把1全部转移到i+1列,然后把0的清空填补前面的空挡,然后就满足了上面的条件,变成了一个子问题

1|0Step 3:

结果发现,如果做到了2,i=2,就没有4列来消了,所以要特殊处理
由于只剩两列了,可以直接暴力
也可以继续推,其实本质就是做到两列同色,然后剩下的那一列不断的往两边move,然后就做完了,感觉十分的人类智慧啊,但似乎有更系统的分治的做法,可以去学一下
至于复杂度证明,上界是n2m的,但可以严格证明最多600000次操作就可做完,事实证明确实如此,可能明天会补
upd:由于颜色不断减小,n2m会带上二分之一的常数,所以可以

5|4T4

6|02024.1.21

136pts,rank4,打的很烂,没有状态,这个排名是因为403的人放假了+我看过T3,这种DP专场我完全打不明白

6|1T1

6|2T2

题目很显然是区间dp,但我们要考虑重复状态的计算
我们可以设f[i][j]表示i到j,两头的括号匹配的方案数,g[i][j]表示两头的括号不匹配,和其他括号匹配的方案数
至于这样为什么不会算重,因为如果只考虑括号,那么f的只会在结尾两种括号数量相等,而g会在中间相等
那么考虑转移,f的简单,直接在里面构造合法串即可,用一个Xi,j表示i到j如果把问号变成星号能不能使i,j全部变成星号,而且数量不超过限制,这样可以简化运算
对于g,可能会计重,就考虑右边的串只由f贡献,左边的可以由g和f贡献,因为f不会由f构成,所以不会计重
计算g是n4的,因为要枚举星号的位置区间,但如果左端点在前面的位置的右端点之内,把左端点右移,右端点最多右移1一位,就可以O(1)计算贡献,不在就暴力扩展即可

7|02024.1.22

8|02024.1.23

这次状态回升了许多,220pts,rank2

8|1T1

简单题,直接O(m2)

8|2T2

赛时看出后面的这一坨式子跟范德蒙德卷积有关,但我不会
手玩出了s=0和1的
正解:
首先,把那个转移式变化一下,就变成了

(s+1)!i=0k1(is)(ki1k)

后面的式子是范德蒙德卷积的形式

标准式是这样的:

i=0k(in)(kim)=(kn+m)

考虑组合意义证明,即n+m个球,要选k个,分成两份,个数分别为n,m,左边选i个,右边选k-i个,枚举了i,就能保证不重不漏

然后和前面的抵消一下,就变成了:

f(n,k)=(s+1)!(k1n)=n!(s+1)!(k1)!(s+1)!=n!(k1)!

要求的式子就变成了k=LR(k+s)!(k1)!×c(k+s)

对于type=1的情况,c恒为1,尝试把那个阶乘写成裂项求和,结论:

(k+s)!(k1)!=(k+s+1)s+2+(k+s)s+2s+2

证明:=(x+s+1)!(x1)!(x+s)!(x2)s+2

整理一下就可以得证

那么由于k=1时分子减的值为0,那么1x的答案就是(x+s+1)!(x1)!s+2,上面的可以写成下降幂的形式直接算

type=2的情况就是要求奇数位的答案,把那个组合数写成下降幂的形式:

(k+s)!(k1)!=(k+s)s+1

前置知识:下降幂转普通幂,xn=k[kn](1)nkxk,证明不会

考虑用第一类斯特林数把下降幂拆开,整理整个式子得:

i=LRc(i+s)k[ks+1](1)s+1k(i+s)k=k[ks+1](1)s+1ki=LR((i+s)k×c(i+s))

后面的可以O(k)拉插,至于如何只算奇数的,考虑容斥,=i=1kxki=1k/2(2x)k,右边的就是偶数的,把2拆出来即可快速计算,斯特林数直接预处理即可

8|3T3

这题感觉十分的巧妙
首先考虑m=0怎么做,先写出曼哈顿距离的公式:abs(axbx)+abs(ayby),由于要这个式子mod2为0,就可以把点分成奇偶考虑,这个是需要两个绝对值都为奇数或偶数,稍微分类一下就变成了两个之间没有公共边的团,取两边最大的即可
然后加上了一些边,由于找最大团没有较快算法,我们还是要挖掘性质
性质1:一个图的最大团大小=这个图的补图的最大独立集大小(补图就是原图中如果两个点没有边就连一条边形成的图)
显然,如果补图中的一个点集没有任何边连接两个点,那么原图中这个点集中就一定全部有边
性质2:这个图的补图是二分图
十分显然,团的补图就没有边了,而两个团之间可能还有边,就可以把两个团分别划归成二分图的一边
那么考虑怎么求最大独立集大小
定理:二分图最大独立集=点数-二分图最小点覆盖
这里的二分图最小点覆盖就是选最少的点,使得每条边最少有一个端点被选,而剩下的点之间一定没有边
定理:二分图最小点覆盖=最大匹配(konig定理(o上面的两个点不会打))
证明:先求出最大匹配,设为M
考虑从右边没有被匹配的点出发,沿着没被匹配---被匹配---没被匹配的顺序遍历,把被遍历到的点打上标记,遍历到不能遍历
那么,最小点覆盖就是左边被打上标记的点和右边没被打上标记的点组成的点集
考虑这个点集的大小,每个点都是一个匹配边的端点,假设右边的不是,那它就会被当成起点遍历,标记,假设左边的不是,那就可以和走到它的右端点形成一个增广路,而一个匹配边如果两边都被选入点集,那么左边的点就可以到达右边的点,于是不存在这种情况,所以一个匹配边对应一个点
为什么是一个点覆盖呢?首先一个匹配边对应一个点,而一个非匹配边一定会有一个端点被选,因为如果左边的没被打标记,右边的被打了标记,那么右边的点就可以到达左边,这种情况就不存在,于是可以
为什么达到了最小?匹配边之间是没有公共端点的所以每个匹配边都要一个点,这种方案恰好达到了最小,即匹配边的数量(最大匹配),于是得证

8|4T4

不会


__EOF__

本文作者longzhaocheng
本文链接https://www.cnblogs.com/longzhaocheng/p/17961418.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   longzhaocheng  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示