zoukankan      html  css  js  c++  java
  • 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,这样减少了每次的计算量。

    Megumin的代码

    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 我们可以考虑每种颜色出现在多少个子矩阵内,由于一个矩阵可能会包含多个相同颜色的格子,那么关键的一步就是避免重复计算,我们对格子进行排序,并规定如果一个子矩阵包含多个相同颜色的格子,那他一定是计算在序小的格子上,这样的话,就可以避免重复,至于计算,很明显格子的下界是不存在的,我们可以枚举上界,当上界确定时,其左右界也可以确定,这样就可以计算了。有一步比较关键的优化是,如果这个格子头上有个相同颜色的格子,那么枚举到那一层就不需要计算了。

    Megumin的代码

    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了,最后求和即可。

    Megumin的代码

    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的时候用线段树去维护区间最小就可以了

    WQF的代码

    1005 最短路 最终答案总可以表示成(a*(2w)+b)其中(0<=b<2*w),所以用d[i][j]表示走到i点,走的总距离模2*w的最小值距离,最短路预处理一遍就行了

    WQF代码

    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(nsqrt{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的关系

    WQF代码

    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)不属于原数列,继续找最小的数,重复操作即可。

    Megumin的代码

    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的代码] (代码什么的,当然是不存在的呀)

    1003 (4/36) 博弈+线段树

    1004 (3/6) ???

    1005 (10/52) 多项式+DP

    1006 (2/18) DP+矩阵快速幂

    1007 (2/357) 数学

    1008 图论+快速读入 观察可得尽量使得两两匹配,保留的边最少,所以考虑二分匹配,树是特殊的二分图,但是本题数据太大了,匈牙利算法和优化的HC算法时限都不够,因为二分图最大匹配=最小点覆盖,本题就转化成求树的最小点覆盖,这是个经典的树形dp,求完之后分类讨论一下最大匹配数与k的关系就行了。另外这题卡普通读入,有点sb

    1009 (3/42) ???

    1010 我们可以利用差分去求解最少需要的机器数。对于总时间的求解,我们可以考虑求出每个机器开始和结束的时间,很显然当当前所需的机器超过已使用的机器时,必须使用新的机器,这样就能求得每个机器的开始时间。对于结束时间,我们考虑倒着求解,利用类似于求开始时间的形式,我们可以求得每个机器的结束时间。(本题机器开启后便不能停止,直到该机器结束,因此可以使用这样的解法)

    Megumin的代码

    1011 即求次短路,我们可以先SPFA求出每个点到1和n的最短路,然后枚举每条边,去更新结果即可

    Megumin的代码

  • 相关阅读:
    LFYZ-OJ ID: 1008 求A/B高精度值
    高精度运算
    【2018国庆雅礼集训】部分题解
    【模板】倍增求LCA
    Luogu1516 青蛙的约会
    loj #10043. 「一本通 2.2 例 1」剪花布条
    我太菜了
    Luogu1280 尼克的任务
    Luogu1091 合唱队形
    Luogu1006 传纸条
  • 原文地址:https://www.cnblogs.com/ACGO/p/7270225.html
Copyright © 2011-2022 走看看