2017年多校
2017 Multi-University Training Contest 1
多校第一场,所以电科没有准备div1的题目
Megumin:怎么全是数学题
1003 求所有点之前不同颜色出现的次数之和,那么可以单独考虑一种颜色,我们只需求出所有不包含这种颜色的pair即可,然后就dfs就好了
[Megumin的代码] (代码什么的,当然是不存在的呀)
1004 NTT
1005 数学(暂时不用补)5/37
1007 线段树+连通分量综合题(暂时不用补)4/11
1008 快速求第k大的数,首先,快排是不可取的,因为n是1e7,会T,但是快排的思想可以用在求这道题上,每当进行一次操作,则会分成两个区间,而我们只需要对k所在的区间进行操作即可,不过这样的复杂度稍大,只能卡过去。另一种做法是,我们首先将询问的位置bi从大到小排序,然后利用STL中的nth_element函数,几乎线性的求解第k大的数,而对于之后的操作,所需要进行计算的数组的大小不大于bi-1,这样减少了每次的计算量。
1009 仙人掌图+求前k大(暂时不用补)13/69
1010 生成函数(暂时不用补)10/36
1012 笛卡尔树 谁来教教我怎么读入 有了读入挂就可以AC了,思路很简单,当你枚举一个区间时,必然是有一个最小值的,那么这个最小值左边的区间和右边的区间的数是可以任意放的,因为无论选取什么数,他们的大小肯定互不相同(好一句废话),那么就有一个组合数了,之后不断枚举这个最小值的左区间和右区间即可。
[Megumin的代码] (代码什么的,当然是不存在的呀)
2017 Multi-University Training Contest 2
1002(12/105) hash+思维
1004(26/150) 数学
1005(22/218) 枚举+区间DP
1007 数论题,首先应该考虑用原根去求解\(f(i)\),之后再对式子化简,总之过程很考验数论推导的水平。
[Megumin的代码] (代码什么的,当然是不存在的呀)
1008 我们可以考虑每种颜色出现在多少个子矩阵内,由于一个矩阵可能会包含多个相同颜色的格子,那么关键的一步就是避免重复计算,我们对格子进行排序,并规定如果一个子矩阵包含多个相同颜色的格子,那他一定是计算在序小的格子上,这样的话,就可以避免重复,至于计算,很明显格子的下界是不存在的,我们可以枚举上界,当上界确定时,其左右界也可以确定,这样就可以计算了。有一步比较关键的优化是,如果这个格子头上有个相同颜色的格子,那么枚举到那一层就不需要计算了。
1010(5/57) 后缀自动机 树状数组 权值线段树 (基本不用补了)
2017 Multi-University Training Contest 3
1001 容斥,数位DP 0
1002 FWT 18
1003 枚举每一个数,计算其是第k大的的次数,相乘后求和即可。但是直接去计算的话,会重复经过很多无用点,即比当前数小的数,因此,用链表去维护所有大于等于当前数的位置,然后从小到大枚举每个数,每次枚举完,就把这个数删除。
[Megumin的代码] (代码什么的,当然是不存在的呀)
1004 字典树
- 有点计数技巧的\(tire\)。首先我们可以一个一个地顺序插入数,在插入的过程中维护\(cnt[]\)表示该节点现在被覆盖次数,维护\(sum[i][j]\)表示第\(i\)位为\(j\)的数现在有多少个,维护\(sub[]\)表示该节点现在出现在第\(i\)个数之前前面某位不完全一样但第\(k\)位一样的数的数目总和(累加)。
- 第i个数\(a[i]\)、\(a[j]\)和\(a[k]\)要满足题意,则\(a[i]\)与\(a[k]\)前某位都一样,在第\(x\)位\(a[i]\)与\(a[j]\)的一样,\(a[k]\)与\(a[j]\)的不一样。所以关键是找\(a[j]\)。\(a[j]\)与\(a[i]\)只需第\(x\)位相同,在计数的时候减去\(sub[]\)就行了。
1005 将2-n个节点分到k个集合中,使得每个集合与1的交集的斯坦纳树的权值之和最大。那么一棵树中的一个节点和其父亲节点应尽量分到不同的集合中,那么这样父亲节点到根节点的路径会被计算两遍,基于这个结论,我们在划分集合的时候,应尽量分离一个节点和其孩子节点。我们从每条边的贡献来考虑,每条边的贡献最多是以较低点为根节点的子树大小,加上k个集合的限制,那么每条边的贡献就是两者取min了,最后求和即可。
1006 对式子进行二项式展开,然后化简下,就可以用NTT去计算了
[Megumin的代码] (代码什么的,当然是不存在的呀)
1007 13
1009 基尔霍夫矩阵 21
1010 DP+cbq分治 34
2017 Multi-University Training Contest 4
1001 多项式+NTT 0
1002 KMP 44
1004 二分+线段树 题意是找一段连续的区间使得区间不同数/区间长度最小,可以表示成diff/len<=k化简得diff-k*len<=0,二分k,check的时候用线段树去维护区间最小就可以了
1005 最短路 最终答案总可以表示成\(a*(2w)+b\)其中\(0<=b<2*w\),所以用d[i][j]表示走到i点,走的总距离模2*w的最小值距离,最短路预处理一遍就行了
1006 图论 1
1007 图论 集合V度数为1的一定要选,先将度数为1的先预处理掉,然后剩下的点都是度数为2的,是个欧拉回路,在回路上隔着取就行了
1008 LCA+并查集 先将轻重链划分出来,不仅仅是为了找LCA,也是为了在合并的时候以轻重链logn的特点,不断合并。
划分为若干条轻重链后,用最小生成树的思想来构造,在(a,b)这个区间内,区间内自己连接,也就是找到a,b的LCA,之后合并到LCA上,c,d也同样这么操作,最后把两个LCA合并起来就行
1010 二分+DP 19
1012 DP
- 令\(dp[i][j][0/1]\)表示两个序列第\(i\)个和第\(j\)个作为结尾,并且是谷/峰。
- 发现转移需要枚举\(i\)和\(j\)再将符合条件的\(dp\)全加起来,复杂度太高。解决方法是另设\(pre[i][j][0/1]\)表示\(sum\{dp[k][j][0/1]|0<k<i\}\)。由于固定了\(i\),所以枚举\(j\)的时候将符合条件的\(pre\)加上。维护\(pre\)只需要在本次\(dp\)计算完后加上即可。
1013 分块 0
2017 Multi-University Training Contest 5
1001 卷积+bitset 肯定是预处理所有的k,本题可以等价于模2意义下的卷积,具体为什么看了半天也不是很懂
1002 AC自动机+DP
- 用了吉司机的思路。如果没有字符串横过中轴线,直接向两边\(dp\)就好。考虑横过中轴线的情况,可以枚举所有的可能的长度为最长长度的串,将出现的串记录在\(dp\)的初始值中,之后接着向两边\(dp\),就不用管横不横过的问题。
其实还有其他更好的方法
1003 可持久化平衡树 (6/78)
1004 莫比乌斯反演+FFT 在有了FFT模任意素数的板子后,便不是问题了,将表达式写出后,利用莫比乌斯反演的经典式子替换gcd即可,最后用FFT求卷积
[Megumin的代码] (代码什么的,当然是不存在的呀)
1005 线段树+李超树 (3/17)
1007 DP (6/64)
1008 0/1背包
- B数组其实是dp[1][j]表示A[1]~A[n]能组合成j的个数。转移方程为dp[i][j]=dp[i+1][j]+dp[i+1][j-A[i]]。移项得dp[i+1][j]=dp[i][j]-dp[i+1][j-A[i]]。
- 求出字典序最小。因为dp[i][0]=1,故只要找到最小的j,使得dp[i][j]!=0,那么A[i]=j;
1010二分+轮廓线DP (3/67)
2017 Multi-University Training Contest 6
Megumin:下次勤奋点,先把水题切了
1001 (66/573) 线段树+扫描线 字典树上建线段树 hash离线
1003 优雅的暴力,从大到小枚举
[Megumin的代码] (代码什么的,当然是不存在的呀)
1004 (5/43) hash
1005 (3/10) 插头dp
1006 (1/15) 状压dp
1007 (34/108) 树状数组
1008 尺取法,通过枚举开始点和结束点去计算
[Megumin的代码] (代码什么的,当然是不存在的呀)
1009 (6/28) 动态点分治
1010 果然博弈题做得还是太少,竟一直想着用SG函数去解决这个问题,果然还是太年轻啊
[Megumin的代码] (代码什么的,当然是不存在的呀)
1011 求出韦恩图七块区域各自的人数,如果有一块人数小于0,说明数据有误
[Megumin的代码] (代码什么的,当然是不存在的呀)
1012 (40/170) dp+倍增
2017 Multi-University Training Contest 7
1001 (3/13) 中国剩余定理+二维NTT
1002 递归 所给的数不是满k叉树就是有一个叉不满,所以只要对不满叉的子树特殊处理就行,除此之外k=1,还得特判,不然树就退化成链,最后会TLE,找下前几项规律就行了
1003 (30/56) 数学+思维
1004 (8/53) 容斥+三元环计数(分块)
1006 状压+分组背包 小于\(sqrt(500)\)质数只有8个,这8个质数可以用分组背包的方式枚举保证不重复枚举,然后二维dp转移就可以了
1007 (18/47) 最小割
1009 比赛的时候没有做出来,有点伤心,事实上,除了p=3的特殊情况,其余满足条件的数均构成三元组,因此可以把模p不等于1的素数先排除掉,然后每个三元组三个数之间是成等比的(取模前),这个比值是方程\(x^3=1(mod p)\)除1外的解,用二次剩余即可计算得到,之后计算一遍即可。
[Megumin的代码] (代码什么的,当然是不存在的呀)
1010 (215/1573) 奇偶性+Lucas定理
1012 (3/7) DP
1013 (10/22) 抽屉原理+循环节
2017 Multi-University Training Contest 8
1001 线段树合并 考虑线段树合并,线段树维护三个信息,区间答案,区间和,还有区间有几个数,区间和和区间个数可以直接相加,这题会卡内存,写的时候要注意
1002 式子的化简倒是毫无难度,关键在于求解\(g[n]\),我只知道\(O(n\sqrt{n})\)的做法,很显然过不去,看了别人的题解发现是打表找规律,但是自己想了想事实上是可以证明的,我们从n-1推导n时,相当于每个数的分子+1,再多加一个1,而分子+1,结果只可能+1或者不变,那什么时候会+1呢,很显然分母是分子的约数的时候。那结果就是多加\(d[n]+1\)了,这样结合约数个数线性筛,就可以\(O(n)\)的去计算了,之后再求一遍前缀和即可。而对于\(f[n]\)的计算,由于\(\frac{n}{i}\)只有\(\sqrt{n}\)个取值,我们可以先预处理莫比乌斯函数的前缀和,然后\(O(\sqrt{n})\)的进行计算即可。
[Megumin的代码] (代码什么的,当然是不存在的呀)
1003 (2/14) cdq分治+归并排序
1004 (55/209) 堆
1005 (4/23) NTT
1006 AC自动机
- 建立AC自动机。每次询问x、y时,将s[x]在AC自动机里跑一遍,把经过的点和fail点都标记了(也就是把所有可能的前缀都标记了)。再将s[y]跑一点,遇到标记的点更新长度。所以要记录每个节点的深度。
1007 (25/184) 阶梯博弈
1009 (26/334) 最小费用有向树
1010 (9/17) 最小割
2017 Multi-University Training Contest 9
1001 DP+hash
- 如果顶点个数没那么大的话,令\(dp[u]\)为\(u\)节点为根的树,向下延伸的最大价值。那么经过\(u\)的最长路要么分别经过两个孩子,要么经过某个祖先的孩子,所以只要枚举祖先更新值就好了。
- 点很多,不能用常规数组去存,于是用map存\(dp\)值。因为修改的点最多\(m\)个,影响到的祖先最多有\(mlogm\)个,用map存足够了。如果查询的是没有修改过的点,其\(dp\)值直接用贪心去求,最多也只有\(logn\)级别的。
1002 先树链剖分,然后用线段树维护,判断x是否在[a,b]之间只要在线段树查询返回的时候,判断区间最值与a和b的关系
1003 (6/73) 极角排序+set
1004 (43/514) 模拟
1006 分成两个集合的最短路很好求,怎样才能使得所有的点对都出现呢,已知任意两个点在二进制表示上肯定至少有一位是不相同的,所以只要枚举二进制的位数,把k个点分成两个集合,需要分logn次即可。貌似这题将k个点随机化排序,分成两个集合也是可以过的。
1007 由于防御导弹的速度是大于攻击导弹的,那么,时间越长,防御导弹就越有可能能与攻击导弹相遇,因此考虑二分。当我们确定飞行时间时,我们可以求出每个攻击导弹的最远位置,而此时防御导弹可处的位置是以攻击导弹为圆心的一个圆内,如果此时防御导弹能够与所有的攻击导弹相遇,那么则这n个圆有交点,这样可以化成圆的面积并去做,然后我们只需要判断面积并是否大于0即可,那么可以考虑面积并边界上的点,这些点必然是某两个圆的交点,那么我们可以枚举两个圆的交点,判断其余点到这个交点的距离是否小于圆的半径即可,复杂度\(O(n^3log)\)。
[Megumin的代码] (代码什么的,当然是不存在的呀)
1008 可以先取出最小的两个数\(a_0\)和\(a_1\),那么\(a_0+a_1\)不属于原数列,继续找最小的数,重复操作即可。
1009 (31/310) DP+筛
1010 DP
- 令\(dp[i][j]\)表示\(s2[1..j]\)能否匹配\(s1[1..i]\),且当前要匹配是\(s1[i]\)和\(s2[j]\)。如果\(s2[j]='.'\)或者字母,直接\(dp[i][j] |= dp[i-1][j-1]\)。
- 若\(s2[j]='*'\)则有三种转移。\('*'\)不匹配字符、\('*'\)匹配前一个字符、\('*'\)“吃掉”前面一个字符。分别对应方程:\(dp[i][j] |= dp[i][j-1]\)、\(dp[i][j] |= dp[i-1][j]\)、\(dp[i][j] |= dp[i][j-2]\)。考虑特殊的字符串,比如空串和\(".*"\)。
2017 Multi-University Training Contest 10
1001 (98/594) bidirectional BFS
- 双向bfs的复杂度比正常bfs要开根号。状态可以hash一下。
- 在搜索中注意step>10的状态不必再搜下去了。
1002 推出递推式后用矩阵快速幂计算
[Megumin的代码] (代码什么的,当然是不存在的呀)