联赛集训考题总结
10.8 xzy
T1
构造七合一.这个先不写了,构造基本上没怎么涉猎.很多题现在还不会.先挖坑,不知道还有没有机会来填了.
T2
一个长为n的序列,你有m次机会可以选择n-1个元素减一,或者直接全部-1,问最多可以操作多少次让序列没有一个元素小于0.
这个很像是俄罗斯方块,相当于一般的俄罗斯方块,每消一行,可以选择一列+1,这样你可以把m也看成第n+1个元素,如果是选择前者的消法,m会消耗1,如果是后者,就等价于选择了第n+1列+1.这样就可以二分答案了,二分这个最多次数x,则最下面x行都必须是满的,于是补齐这x行,看看补齐的代价是不是小于x,如果小于说明合法,否则不合法
T3
空间复杂度...大模拟,比时间复杂度不知道毒瘤多少...收货主要就是锻炼了自己的代码能力,思路的条理逻辑性.
10.9 the_despair_ ljq
T1
好题,有很多种方法,倍增floyd,分数规划都可以.写了题解
T2
用map优化连边,直接建图直接跑DAG最短路即可.
T3
好题,倍增直接写是\(O(nlogn)\)的,树的直径+st表,可以把询问复杂度降到线性.把直径抠出来,利用任意一点在树上的最远点一定是直径的某个端点的性质.
10.10 Tyher
T1
套路题,求乘积最短路,直接对每一条边取log跑普通最短路就可以了.
T2
插头dp/状压dp,不会插头dp,于是写了状压,细节很多很多.主要的技巧是缩减状态,把格子黑白染色分块,黑白不相互影响,转移的时候判断合不合法就可以了.考场上想了好久好久网络流,下次看到n*m图m很小就要注意应该是插头dp或者状压.
T3
gcd和与或运算最多只有log种取值,于是就可以直接序列分治,考虑怎么统计覆盖中点的区间,记录一个往右的前缀和和往左的前缀和,把gcd相同的和或起来相同缩成一块,注意最多只有log块,然后暴力枚举两边,复杂度\(O(玄学)\)这个复杂度怎么算啊...
10.11 zkj小胖
T1
毒瘤四合一.
sub1 dp/欧拉路.dp设状态\(dp[i][j][a][b]\)表示i到j这一段序列的烟霞的最大答案,左端点为a色,右端点为b色.枚举一个\(k\in (i,j]\),考虑合并答案.分为三种转移.一种是不拿其中一个区间的烟霞,一种是把两个区间接起来,一种是接起来之后再翻转过来.由于颜色数很少,就对颜色建图,一朵烟霞看做一条边,然后要使边权和最大,由于边很多,所以优化连边,对每一对颜色之间所有的边,最大值连边,次大一条边,剩余的所有看做一条边.最后直接dfs找最大和就好了.理论复杂度很高,实际很快.
sub2 结论题,\(ans=\sum w\),递归证明,一定存在两个联通块之间是用最短边相连的,因此为了答案最大化我们只走最短边一次,然后再分别考虑两个联通块,对于每个联通块又一定会要经过其最短边一次,也就是说,我们一定会将最短边,次短边,等全部经过一次,所以只需要将所有烟火的美丽值之和相加即可。
sub3 dp,还没写,挖坟
sub4 费用流/并查集(类kruskal),参见棋盘上的守卫.一个太阳相当于一条边,我们要找到一个基环森林,使得每个月亮的出度都是1,权值最大.这样弄一个tag标记联通块里有没有环.
T2
毒瘤二合一
sub1式子是\(ans=\sum_{d|n}\frac{n}{d}*\varphi(d)\),这样由于你可以先对n质因数分解,由于d是n的约数,所以d的质因子一定是n的质因子,考虑我们为什么要\(\sqrt d\)求\(\varphi\)因为,我们要枚举约数,质因子最多只有log个,预处理质因子,就可以直接通过质因子和类似线性求\(\varphi\),即\(phi[prime[j]]=phi[i]*prime[j]\)的方法了.复杂度\(\sqrt nlog_2n\),实测非常快,但复杂度是错的.题解也有十分复杂的方法.不想推导了.
sub2 考虑按位操作,统计每一位的1的个数.分类讨论,被减数当前位分别是0/1时,减数的范围,直接把每个前缀和丢到树状数组里,区间查询就可以了.
T3
点分治,小胖数据随机,好多人都暴力水过去了...考虑这题怎么做,统计树上的路径点权和为k的倍数的方案数,k只有30,可以离线做.点分治对每一棵子树dp转移即可,由于是一个一个点往里添加,所以dp的转移是\(O(k)\)的.
10.12 fdf
T1
还不会.挖坑.
T2
如果对子树按\(\frac{sum_i}{size_i}\)从小到大排序,考虑交换两个子树的代价\(sum_jsize_i-sum_isize_j\),由于\(\frac{sum_i}{size_i}\leq\frac{sum_j}{size_j}\),则\(sum_isize_j-sum_jsize_i\leq0\)所以直接排序即可.
T3
注意到第一问的答案只有可能是2或者3(至于为什么...我也不知道...).不管怎样都至少有一棵树只需要断掉一条边.求出另一棵树的所以边在这棵树的lca,考虑树上差分维护每一条链上经过的路径数,然后统计答案即可.完全忘记树上差分这个套路...求lca一定要tarjan(卡时),顺带复习了tarjan求lca.
10.15 YL
T1
感觉现在又稀里糊涂了...坑(好多坑...)
T2
Trie树启发式合并,考虑把边从小到大排序,每次当前边都会把两个联通块联通,贡献等于这两个联通块里异或值大于当前边的点对数,这个可以直接用trie树统计一下就可以了.合并要把小的联通块合并到大的里面去.
T3
多源最短路+kruskal最小生成树+货车运输
10.16 DAY1
T1
meet in the middle,考场写的枚举子集可以过,但是两个数组混用了,然后就为组拖后腿了...
T2
DP,考虑把1到n的顺序排列交换为它给你的序列,每个数原始都在和它数值相等下标下,要移动到目标,设为pos[i],那么从i到pos[i]这一段的所以交换,都必须i到posjixu顺序进行,假设pos[i]在i的右边,那么在i的左边的数要和i这个位置的数交换,必须发生在i和i+1交换之后,那么就出现了一些制约关系,我们可以通过这些制约关系来dp,dp[i][j]表示操作序列前i个数中,第i个数是第j小的的.如果是右边先转,则只能从右边(>j)转移而来,如果是左边先转,则从左边(< j)转移,否则就从任意位置转移,这个可以前缀和优化.
T3
直接二分答案,暴力check,加一句if(!check(ans))continue;即可ac.
10.17 DAY2
T1
简单贪心,被我写成线段树优化连边最大流...还写挂...直接先按左端点排序,考虑从左到右加点,找区间匹配,每次左端点合法的加入堆中,堆维护右端点最小.
T2
神仙dp,题目就是有标号树的形态计数,状态是\(dp[i][j]\)表示节点个数为\(i\),最大深度不超过\(j\)的方案数.如果无标号考虑合并两棵树,最大深度不超过\(j\)的状态,一棵节点数为k,一棵为i-k,那么其中一棵的深度必须是\(j-1\),接到一棵深度为\(j\)的树上,如果有标号,要乘上一个组合数\(C(i-2,k-1)\),意为两棵树分配标号.统计答案恰好等于就是不超过n减去不超过n-1的.
T3
很容易发现联通块个数就是点数减去边数,给定区间\([l,r]\),点数已知了,那么只要检查连边,而连边只会范围内的点之间产生,把u到v的边抽象成平面上一个点,很经典的二维数点问题,树状数组或者主席树做就好了.
10.18 DAY3(zsy)
毒瘤QAQ
T1
求三位偏序,数据范围\(2*10^6\),显然不能直接cdq(之前三维偏序都是写的cdq套cdq,导致今天根本没法卡常qaq).那么考虑容斥.对于一对需要算到答案里的点,它一定会被统计到下面的所有三个sigma中;对于一对不需要算到答案里的点,它也一定只会在下面的sigma中被计算一次(有且仅有一对大小关系是相同的,如果\(a_1,a_2\)的大小关系不同于\(b_1,b_2\),则\(c_1,c_2\)的大小关系一定同于其中一个,反之,如果\(a_1,a_2\)的大小关系同于\(b_1,b_2\),则\(c_1,c_2\)的大小关系一定不同于其中任何一个),那么答案就会等于如下式子:
cdq可以求出每一个位置的偏序个数,而这种方法不行.
T2
不会,,,
T3
不会...
10.19 FLASH
今天的题感觉出得很好哇.
T1
一个类似斜率优化的东西,事实上就是要找到对于一对\(A,B\).要求使\(\frac{A}{a_i}+\frac{B}{b_i}\)最大的i.不妨把每个a,b抽象成平面直角坐标系上的点,把限制抽象成一个不等式的图像,不难发现这个不等式图像的边界的斜率一定是小于0的,于是要求在边界的点,其实就是要找一个凸壳,我们在化简式子的时候会发现要将一个正负性不确定的数同时在不等式两边相乘,这样就变成要维护两个凸包.分类讨论很麻烦,于是可以先按照a排序,在维护斜率递增的左下凸包就可以了.(卡精度啊QAQ)
T2
高斯消元的原创题.flash真的很爱化学呢...高斯消元没学透,这道题消元要注意的主要是,对于每个变量,当你找不到方程这一位上有系数的时候,跳下一个变量,方程的指针暂时不动,这样一直把所以的变量消掉就可以了.(-0.0 QAQ)
T3
这题覆盖面很广,很好的练习题啊.倍增+二分答案+最长上升子序列LIS+树状数组,首先二分一个答案,然后算出它们经过t之后的位置,这时的相对位置的最长上升子序列如果大于k说明合法,否则不合法,这样第一问就\(O(Nlog_2^2N)\),第二问:很容易证明这个转移是满足最优子结构性质的,于是可以抽象成一颗树的结构.用树状数组维护前缀的最大值的字典序最小的位置(有用的决策).满足在树上的深度最大,要比较字典序,只要找到两个转移节点的到它们lca的最小值即可(以上的部分是公共的),倍增跳就可以了.
10.20 DAY4 wxh
暴零了...
10.22 YCB
T1
线段树优化dp,第一次考试的时候遇到这种题(见识短浅QAQ),知道套路之后感觉挺简单的,状态是\(dp[i]\)表示对b的限制为i的状态下的最大答案.分两种情况讨论,\(a_i<=b_i\)和\(a_i<b_i\),前者的转移是:从\((b[i],n]\)中间选一个最大的答案,转移到当前点\(a_i\),然后更新当前点的最大值.后者的转移就是,从\((a_i,n]\)中选一个最大值转移到a,而在\((b_i,a_i]\)之间的状态同样可以答案加1,同样更新a点的最大值.于是线段树维护区间最大值,做区间加和单点修改就可以了.
T2
可以用dsu on tree做,但是感觉ycb那个写法十分妙啊,于是就写的那一种.具体算法流程就是:
统计颜色数要用到一个非常妙的差分,假如不考虑深度的限制,对于相同的颜色的点开一个set,set维护的dfn,每次取出一个点,这个点加1,如果有前驱就在前驱和这个点的lca处-1,有后继就在后继-1,有前驱也有后继,就在前驱后继的lca处+1,这样差分,可以维护子树内的不同颜色数.
如果有深度的限制,那么就一定要按照深度的顺序由浅到深加点,注意不能由深到浅,如果由深到浅,就会出现两个点的lca会在两个点之上,那么差分树的结构就被破坏,不是按照层序了.
对每个深度建立一棵主席树.
总结一下就是:
树链剖分求lca,顺便算出dfn序,开vector存一下每种深度的点.
把点按照深度顺序插入对于的颜色的set中,找出按dfn排序的前驱和后继,进行树上差分.
差分的树用可持久化线段树维护.
查询就查询对应深度的线段树里对于dfn序的区间就可以了,注意每棵线段树都是对应的深度,不是dfn序列.
T3
\(dp[i][j]\)表示处理了i个,长度为j的本质不同子串的个数,考虑直接转移
这其实就是枚举拿或者不拿,本质上就是组合数,由于要求本质不同,考虑容斥,减去算重的,对一个字符串\(\rm yyyyyyaxxxa\),x表示任意非a的字符,y是任意字符,那么第二个算重的只有可能是第一个a和第二个a共用了前面的yyyyy的前缀,减掉这个算重的就可以了.预处理出\(pos[i]\)表示i位置前面的一个和s[i]相同的字符位置,按照上面转移就好了.