2020牛客国庆集训派对day1

(5 mins to read)

题目都不难,貌似是去年欧洲区域赛题

A

给定一个长度为n的字符串,问你最少在 后面 添加多少个字符,使其变成回文串$n \leq 4 \times10^5$注意是只能加在后面,所以马拉车一下就行,找一个最长的回文后缀,然后补齐前缀即可(如果是任意添加,那答案就是正串和反串的LCS,只能$n^2$

B

给定一个长度为n的数组a,定义$g(i, j) =gcd(a_i,\dots,a_j),m(i,j) =max(a_i,\dots,a_j)$,求$\sum_{i=1}^n\sum_{j=i}^ng(i,j)m(i,j)$$n \leq 2\times10^5$很套路的题,gcd可以分成不同的log段枚举右端点,利用单调栈和线段树动态维护后缀最值,然后二分gcd不同的段的左端点即可一种更好的写法是利用路径压缩,可以去掉一个log令$g_i$​表示i到当前右端点的gcd的值,$nxt_i$​表示i左边第一个g与$g_i$​不同的点,不断跳$nxt_i$​,当i和$nxt_i$​的gcd相同时,就合并$nxt_i= nxt_{nxt_i}$

C

给定一棵树,每次可以修改一个点的父亲,问最少几次操作变成一条链答案就是所有大于2的点的度数-2的和因为度数$\leq 2$可以不管,$>2$,就必须把其它的点挪走

D

给定n个点,1条直线,参数r让你在这条直线上选择一个点作为圆心,作一个半径为r的圆,覆盖最多的点,求点数$n \leq 3 \times 10^5$考虑每个点能被覆盖的都是直线上的一个区间,求出区间后,就相当于用一个长度为$2r$的区间覆盖最多的区间,因为区间的长度都是小于$2r$的,所以离散化之后差分前缀和取max即可另一种做法是先按区间的左端点升序排序,枚举第i个区间作为最后一个被覆盖的区间,贪心的考虑肯定将圆心放在该区间的左端点上(即尽可能的靠左),此时覆盖的点的个数就是前面所有右端点$\geq$该左端点的区间个数,pbds即可

E

求$\sum\limits_{i=n}^m \sum\limits_{d\mid i} 1$$n\leq m \leq 10^{12}$转成枚举因数d的贡献就是一个整除分块了

F

有n个数,让你找k个使得它们相与的结果最大从高位往低位贪心即可,该位有超过k个1就取

G

给出q个字符串$s_i$​,询问长度n的字符串中有多少串不包含这q个字符串$\sum\limits_{i=1}^q |s_i| \leq 100$,$n\leq10^9$到最后才想到ac自动机,一开始一直在想容斥对这q个串建出trie图,然后标记出不合法的位(每个串的末端,以及每个串可识别的后缀)接下来就转成图上n步路径问题,对邻接矩阵作快速幂即可

H

给出两个字符串s和t,只包含字符AGCT,保证t可由s交换字符得到,问最少的交换次数考虑置换,对于一个长度为x的循环,需要x-1次交换,所以只要贪心的最大化循环个数即可,即最小化每个循环的长度。由于只有这四种字符,所以只有可能是1234元环,从小到大搞就行

I

给出一张无向图,多次询问只考虑给定的一个大小为s的点集时连通块的个数询问的点集大小和不超过$10^5$也很套路,考虑度数小的点,直接暴力枚举所有出边,如果在当前点集中就用并查集合并再考虑度数大的点,对于度数大的点和度数小的点的边,我们在度数小的点中已经枚举了,所以只考虑度数大的点和度数大的点之间的边,设置阈值$n\sqrt n$​,显然这样的点个数不超过$2\sqrt n$​,直接预处理出这些点之间有没有边(用一个二维矩阵存储),再对于点集内所有度数大的点单独做一次二维for循环合并即可

J

给出一个数组,然后询问是否存在相应的大小关系的三元组$(x_1, x_2, x_3)$总共有13种,分别做即可

  • 三个相等111,看有没有一个数出现3次以上,map记录
  • $x_1=x_2$​,枚举$x_2$​,如果前面有相等的$x_1$​,就看后面有没有大于和小于$x_2$​的,112,221
  • $x_2 = x_3$​,上一种倒着做,122,211
  • $x_1=x_3$​,对每种数,取最左出现和最右出现的,然后只要看两者间的最大值和最小值和这个数的关系,121,212
  • $x_1<x_2<x_3$​,枚举中间数,123
  • $x_1>x_2>x_3$​,同理,321
  • $x_1<x_2>x_3$​,枚举中间数,然后看左右两侧小于$x_2$​的最大的和最小的数的大小关系,132,231
  • $x_1>x_2<x_3$​,同理,213,312