SD NOIP赛前

Day1

T1

题意:给定 \(S,T,|S|,|T|\le 5000\)\(q\le 3\times 10^5\) 询问,给定 \(k\),求最少多少个 \(S\) 顺次相接 不是 \(k\)\(T\) 顺序相接得到的串的子序列。

题解:求出 \(S\) 的第 \(i\) 个位置开始匹配一个 \(T\) 最多能匹配多长(\(S\) 可以接好几次),然后找到循环节。然后就好做了。

T2

题意:有一棵树,每次询问有多少个有序四元组 \((a,b,c,d)\),使得 \((a,c),(b,d)\) 这两条路径交点恰好是 \((x,y)\)\(x\not = y\))。\(n,q\le 3\times 10^5\),取模。

题解:经典题。答案就是两个点的 \((n-sz)^2 - \sum size_{son} ^2\) 乘起来,其中 \(sz\) 是将这个点当成根时其包含另一个点的子树的大小。然后分讨 \(u,v\) 一个点是否另一个点的祖先。

T3

题意:设 \((a,b,c)=dis(a,b)+dis(a,c)+dis(b,c)\),求对于每一个点 \(x\),权值最大的包含 \(x\) 的三元组的权值是多少。\(n\le 3000\)

我的做法:你直接枚举每一个 \(x\),将其作为根,然后枚举一个点 \(a\) 作为剩下两个待选点的 LCA,注意一种情况是这个点就是 \(x\),这个要特殊处理。然后对于 \(a\) 的两个子树算。

一种情况是选 \(a\),二分即可。另一种情况可以对大小小的那棵子树双指针或者二分,两个取复杂度小的即可。这样跑的很快。

正解是枚举三个点的中间点,随便设一个根,然后枚举其中两个点的 \(LCA\),这样你可以枚举那两个点,这样的点对总共是 \(n^2\) 的。然后你就对于这个点子树外面的点种考虑剩下一个点,这样的点的答案也可以算出来。然后双指针即可。复杂度 \(O(n^2 \log n)\)。瓶颈在排序。

T4

高妙题。

题意:有 \(n\) 张牌 \(a_i\),牌面数字是 \([0,4]\) 的整数,打出一张 \(a_i\) 可以从目前的牌顶拿 \(a_i\) 张牌(空了则不拿),然后丢掉这张,每次询问我把 \(a\) 重排成(从牌顶开始) \(a_s,a_{s+1}...a_n,a_1,...a_{s-1}\),然后询问一开始拿 \(k\) 张牌,最多打出 \(p\) 张牌最多能取走多少牌。

\(nq\log n\) 的暴力很简单。每次打出能拿的最大的即可。

先断环成链,将 \(s\) 的限制变成序列从一个位置开始的限制。

牌面的可能性很小,可以从这里入手。先考虑 \(0\) 有什么用。显然是占位置的,而且你不会打出它(打出也没用),所以你做一个前缀和,\(sum_i=sum_{i-1}+a_i-1\),表示你从前往后取完 \(i\) 目前剩下多少张牌能取但没取,那么显然能够发现这玩意满足差分性。所以对于从 \(s\) 开始的 \(sum'_i\) 就是 \(sum_i-sum_s\)。那么一开始取了 \(k\) 张牌,相当于把 \(sum_i+=k\),然后求第一个 \(sum_i<=0\) 的位置就是取不下去的位置(实现起来就是找到 \(s\) 后第一个位置 \(i\) 使得 \(sum_i\le sum_s-k\))。这个就是不考虑取走几张牌限制(称之为无限火力)最多取走多少。然后显然,这时你把 \(0\) 当成 \(1\) 已经没多大影响了,因为在你目前的合法最多位置之前每次都会打出最大值,而这时的最大值显然存在且非 0。唯一的影响是答案超过这个端点时需要取 \(\min\)

接下来已经没有 0 了。你的 \(0\) 当成了 \(1\)

然后继续考虑 \(1\),类似地,显然你有更大的牌打必然不会打这张牌,于是你做一个新的前缀和 \(b_i=b_{i-1}+a_i-1\),其中当 \(a_i=1\)\(b_i=b_{i-1}-1\)

和前面同样的道理,你求出第一个不取 \(1\) 取不下去的位置 \(i\) 满足 \(b_i\le sum_s-k\),然后下一个位置 \(j\) 就需要满足 \(b_j < b_i\) 了。后面的以此类推。

然后你考虑能打出多少张 1,显然当你打出一张 1 的时候,你前面所有 \(2,3,4\) 都要打出来了,那么你只需要考虑到打出大于 \(p\) 个之前一个就行。这样,你就计算出了打出 1 的牌数。

然后把 1 就可以看成 0 了,之后把所有的 0 当成 2 继续处理 2,之后继续类似地处理下去,直到剩 4 了你就能打的全部打出。

有 1145141919810 点毒瘤。但是确实很妙妙。

CF1558E

*3000

考虑二分答案,然后考虑已知点集合(内部可以随便走),然后考虑从集合中每一个节点去搜索并标记(搜不下去了就把搜不下去的这个点标记一下然后不搜了),然后如果搜到一个已经标记的节点,那么判一下能不能通过两部分走到的点把这个点也给走了,能走就实现了一次增广。实现上只需要记录每个点上一个走到的节点。发现一次至少增广一个点,至多遍历一遍图,复杂度 \(O(nm\log V)\)

P8207

考虑转化一下,变成对于每一个 \(d\),将 \((kd,md)\) 之间连接 \(kmd\) 的边,那么对于一个 \(d\) 只需要保留最小编号的节点到其他点的边跑 kruscal 即可。

复杂度 \(O(n\log v \log n)\)

LOJ3818

___题。懒得记了,爬了ppt。

考虑建图,将一个车位的两辆车从上面向下面连一条有向边。若一个车位为只有一辆车则不连边,若一个车位为空则为一个额外空间。由于每种车只有两辆,所以若将图看成无向,则它一定形如若干个链或环。

首先对于入度为 \(0\) 出度为 \(0/1\) 的点,只需一次操作即可将其删除。

对于入度为 \(0\) 出度为 \(2\) 的点,我们需要两次操作和一个额外空间去删除这个点。

那么对于一条链,我们肯定是需要从左到右找到每个入度为 \(0\) 的点,然后将其删除。

对于一个有入度为 \(0\) 的点的环也是类似的,但是可以发现,环会占用两个额外空间。

特别地,对于一个入度出度均为 \(1\) 的环,我们需要一个额外空间处理。

所以我们的最优策略就是,先删入度为 \(0\) 出度为 \(0/1\) 的点,再删每条链,之后删每个环。若有一步无法操作则无解。

时间复杂度 \(O(n)\)

CF1610F

*3000

首先注意:要求差恰好是1,而不是小于等于1。

首先只有 1 边的时候,可以把每个边数是奇数的连到一个新建的点上跑欧拉回路确定边的方向。

当有 2 边的时候,考虑建模。首先把 \(i\) 拆成 \(i,i'\),然后对于 1 边连 \(u,v\),对于 2 边连 \(u',v'\),然后你对于 \(i\),如果 \(i,i'\) 的度数都是奇数,连 \(i,i'\)(均为无向),如果仅 \(i\) 度数是奇数,连 \(S,i\),若仅 \(i'\) 度数为奇,连 \(S,i'\)。能够发现,这样能够使得每一个 1 边个数为奇的点都合法。而 1 的边数为偶的显然无论如何不可能合法。于是最后跑欧拉回路确定边方向即可。

CF1528D

*2500

考虑以每一个点作为起点跑 dij,那么对于一条边更新的时候,它可以作为 \((a,b+v,c+v)\) 去更新每一个点。那么你拿出一个点更新的时候,枚举边先按原方案更新,然后枚举每一个点,\(dis_i=\min(dis_i,dis_{i-1}+1)\),之后取出当前最小的点继续更新即可。注意要跑 \(n^2\) 的朴素 dij,不然复杂度上天了。复杂度 \(O(n^3)\)

Day2

T1

题意:有矩阵,有若干个位置填了0,要求填完矩阵使得 \(a_{i,j}+a_{i,j+1}+a_{i+1,j}+a_{i+1,j+1}=1\)

题解:直接隔一行跳着填 1 或者对列做。

T2

题意:给定 \(m\times k\) 长的序列,其中值为 \(i\) 的数恰好出现 \(k\) 次,求有多少子序列满足不存在 \(i<j<k\)\(a_i>a_j>a_k\)\(a_i<a_j<a_k\)

\(m,k\le 300\)

题解:首先可以发现最多选四种数,选多了就必然寄了。按相对大小,把选的编号为 \(1,2,3,4\) 然后选数的形式是中间是 \(1,4\) 随便选,两边只能分别是连续的一段 \(2,3\)

然后你枚举最小最大值,然后枚举左右端点,钦定左右端点必须选,中间的 1,4 随便选,但是必须保证有一个 \(1\) \(4\) 选上,然后左右两边必须选大于 1 且小于 4 的数。分讨一下发现可以是 \(2...(1...4...1...)3...\) 也可以是 \(3...(1...4...1...)2...\),也可以左右两边选同一种数,或者一边选一边不选,或者干脆都不选。实现上你对数的选法做个前缀和然后左右选的方案加一相乘即可。

当然这时会漏只选一种数的情况,补上即可。

具体一点,你设 \(f_i\) 表示 \([1,i)\) 中选某一种值在 \((1,4)\) 的数,且至少选一个的方案数,\(g_i\) 则是在 \((i,m\times k]\) 中选。那么大概就是形如 \((g_r+1)\times(f_l+1)\)

然后你枚举了左右端点,对于一个端点答案就是 \(2^{r-l}\times (f_l+1)\times (g_r+1)\)。这个显然是容易按左右端点拆开分部计算的。

这个式子唯一的问题就是当左右端点是同一个数的时候,另一个数必须选上一个。

你发现这个的柿子是 \(2^{cnta_r-cnta_l}\times (2^{cntb_r-cntb_l}-1) \times (f_l+1)\times (g_r+1)\)。也即比上一个柿子减掉\(2^{cnta_r-cnta_l}\times (f_l+1)\times (g_r+1)\)。这个柿子也相对于左右端点独立。也是能算的。

于是算完了。

T3

题意比较复杂。不写了。

关心 \(a_2=t\),考虑最后必然要放 \(n \operatorname{mod} t\)\(a_1=1\) 来解决这部分没人填的。

之后 \(n\) 都是 \(t\) 的倍数了。你发现,之前要填 \(a_1\) 的话,必然一次连续填 \(t\) 个,所以你可以把这样的 \(a_1\) 看成另一种 \(a_2\)

这时你就可以递归子问题 \(\lfloor\frac{n}{t}\rfloor\),然后 \(a'_i=\frac{a_i}{t}\) 了。

发现你只关心 \(n,t\) 和目前有几个等价的,可以设 \(f_{i,j}\) 表示当前的 \(n\)\(i\),有 \(j\) 个不同的 \(a_1\) 可以填的方案数。

转移的话就 \(f_{i,j}\rightarrow f_{i/t,j^t+1}\times j^{n \operatorname{mod} t}\) 即可。而且由于方案数的模数很小,\(j\) 需要对 \(p\) 取模。所以 \(i\) 的个数是根号级别,\(j\) 是模数,转移有 \(m\) 个,复杂度 \(O(\sqrt{n}mp)\)

每个 \(f\) 有一个初始值,显然初始你可以以当前的 \(a_1\) 作为你系统中的 \(a_L\),于是全用 \(a_1\) 填, \(f_{i,j}=j^i-(j-1)^i\),但是注意这里如果你将指数模 \(mod-1\),那么会出事,因为这里的 \(i>0\),但是你有 \(0^0=1\),但是指数取模之后变成的 \(0^0=0\)。所以你判一下即可。

Day4

T2

题意:有一个单向环,长度 \(10^9\),有 \(k\le 500\) 个棋子放在一些不重复位置,每次操作会随机一个位置并删掉与其最近的棋子,求期望几次操作删掉第一枚棋子。

题解:首先用棋子把环分成若干段,长度分别是 \(b_1,...,b_n\),则每次会加权平均随机一个位置,然后将其值加一,当任意位置 \(i\) 的前缀和大于等于 \(i\) 时就会删掉第一枚,所以你可以设 \(f_{i,j}\) 表示考虑前 \(i\) 段,当前已经合法做了 \(j\) 轮操作用多少种方案,转移就是 \(f_{i,j}\times C(k+j,k)\times b_{i+1}^k \rightarrow f_{i+1,j+k}\)。然后你用总方案减去合法的就算出了不合法的,剩下的就简单了。

T3

题意:选无序四元组 \((a,b,c,d)\) 覆盖一棵树,其中 \(a\)\(b,c\) 父亲,\(b\)\(d\) 父亲,要求四元组选的数不能相交,求所有选择方案的个数和所有方案中四元组总个数。

题解:记 \(f_{i,0/1/2/3},g_{i,0/1/2/3}\) 表示 \(i\) 目前未匹配/匹配了长度为 1 的儿子/匹配了长度为二的儿子/匹配好了的方案数/总个数,则转移易得。

T4

有树。有若干次询问。求距离 \(u,v\) 其中至少一个不超过 \(d\) 的点数。

转化为求距离 \(u\) 不超过 \(d\) 的,距离 \(v\) 不超过 \(d\) 的和距离 \(u,v\) 都不超过 \(d\) 的。

发现第三个也可以转化为距离路径中点距离不超过 \(d-l/2\) 的,于是都可以点分治。

CF865C

考虑设 \(f_{i,j}\) 表示当前打了前 \(i\) 关,系统时间是 \(j\) 的期望时间,\(s\) 是最小的重开期望时间,则有 \(f_{i,j}=\min(s,(f_{i-1,j-a_i}+a_i)\times p_i+(1-p_i)\times (b_i+f_{i-1,j-b_i})\)。发现 \(s\) 不确定,但是可以二分,当求出的最优值小于等于二分值时这个值可以取到。

codechef题

题意:有 \(n\) 个人,每个人能力值互不相同,\(n-2\) 次从剩下的人选两个斗殴,能力值高的会胜利,另一个死了,求所有情况下剩下两个人中能力值较低那个的能力值之和。

题解:先按权值从大到小排序,考虑最小的那个什么时候会存活。推一下柿子,发现是 \(\frac{1}{C(n,2)}\)。然后可以设 \(f_{i}\) 表示前 \(i\) 个人答案的期望,则有 \(f_{i+1}=(1-\frac{1}{C(i+1,2)})\times f_i + \frac{1}{C(i+1,2)} \times v_{i+1}\)。最后答案乘一个方案数即可。

P4707

min-max容斥。

柿子是

\[\max_k(S)=\sum_{\emptyset \not=T\subset S}C(|T|-1,k-1)(-1)^{|T|-k}Emin(T) \]

首先把 \(k\) 变成求 \(n-k+1\) 大。

然后设 \(f_{i,j,k}\) 表示前 \(i\) 个元素,\(\sum p=j\),把式子里的 \(k\) 换成这个状态的 \(k\)\(\sum_{\emptyset \not=T\subset S}C(|T|-1,k-1)(-1)^{|T|-k}\)

则当 \(i\) 不选的时候,转移是 \(f_{i,j,k}=f_{i-1,j,k}\),选的时候就是组合数和 \(-1\) 的指数会变,但是你组合数拆开,发现就是 \(f_{i-1,j-p,k-1}-f_{i-1,j-p,k}\)

初始设 \(f_{i,0,0}\)\(1\) 即可。

最后要乘上 \(Emin(T)\),即在你选中的集合中选中一个的期望次数,也即 \(\frac{1}{\sum p}\)

ARC114E

考虑每一条线必须在哪些线之前选,就可以算出选它的概率,然后把所有概率相加就是期望。显然一条线必须在其更靠近黑点的线之前选,如果被黑点夹着则必须在被夹的线中先选。

AGC019F

P5644

先把题意转化为死掉的猎人不断选一个人直到选的人没寄。然后把第一个人最后么得的概率容斥成钦定有 \(i\) 个人在 \(1\) 之后寄的概率。

然后有柿子 \(ans=\sum_T (-1)^{|T|} G(T)\)\(G(T)=\frac{w_1}{w_1+\sum_{i\subset T} w_i}\)。发现这个 \(G\) 可以类似上一个 min-max 容斥题一样,设一个 \(f_{i,j}\) 表示前 \(i\) 个数,\(\sum w_i\) 之和是 \(j\) 的答案,然后枚举下一个数选或不选即可。

原题数据范围需要套一个分治 NTT,没什么意思。

P6478

考虑把恰好 \(k\) 对容斥成钦定有 \(k\) 对,然后计算方案数最后除掉总方案数。那么你设一个 \(f_{i,j}\) 表示 \(i\) 子树内选了 \(j\) 对点,那么就是经典树形dp,转移枚举 \(i\) 和子树内的点匹配即可。

然后枚举根匹配了几对,乘上剩下随便匹配的方案数即可。

CF1278F

Day5

T2

题意懒得写了。发现可以转化成一个目前集合中数的个数总数的矩阵,\((0,0)\rightarrow (n,n)\) 求经过节点最大值最小的路径,一次交换只改变一行,那么预处理正着和倒着的 dp,然后对这一行暴力重做 dp 合并前后缀 dp 值即可。

T3

给定一张图,每个点有 \(k\le 12\) 种颜色之一,求生成树的总数,满足生成树中所有颜色恰好出现一次。两棵树不一样当且仅当它们看起来不一样。

题解:设 \(f_{S,i}\) 表示以 \(i\) 为根,当前树的颜色集合是 \(S\) 的方案树,\(g_{S,i}\) 是多保证了 \(i\) 度数是 1 的方案数。

则转移:\(i,j\) 有边,\(f_{S,i} \rightarrow g_{S|col_{j},j}\)\(g_{S1,i}\times f_{S2,i} \rightarrow f_{S1|S2,i}\),其中 \(S1,S2\) 的交集只有 \(i\) 的颜色。并且你需要钦定 \(S1\) 包含 \(S\) 中除 \(i\) 以外的最小颜色。

复杂度 \(O(n\times 3^k)\)

LOJ3151

P7142

考虑刻画最短路。设 \(f_{i,S1,S2}\) 表示最短路是 \(i\) 的集合是 \(S2\),最短路不大于 \(i\) 的集合是 \(S1\),则枚举与 \(S1\) 不交的集合 \(S3\) 作为最短路 \(i+1\) 的集合,然后可以乱做。

CF1439A2

直接按行从后往前一行一行归零,然后对第一二行按列归零变成一个 2*2 的东西。

P8416

上界是 \(2(n^2-n)\)。然后一种做法是对于前面每一行每个数两次操作,最后一行每个数一次操作。但是超市了。考虑怎么不被超市。可以对于每一行,找出应在这一行的数形成的某个环,然后就可以省一次操作了。比较难实现的是 \(O(n^2)\) 维护这些。

CF1521E

显然至少有 \({\lfloor \frac{n}{2}\rfloor} ^ 2\) 个填零的,于是能算出 \(n\)

按照格子的横纵坐标排序。具体是先把横奇纵偶的放前面,然后是全奇的,然后横偶纵奇,然后内部按字典序排,把所有数填就可。

CF1615F

Day6

T1

最毒的一道。

题意:给定括号序列,要求一个括号序列,越前面的位置和给定序列相同权值大 \(2^i\),要求权值第 \(k\) 大的括号串,满足其为合法括号序列且没有三个连续的相同括号。

做法:从前往后确定每一个,设 \(f_{i,j,S}\) 表示长度 \(i\),左括号比右括号多 \(j\) 个,且前两个括号状态是 \(S\) 的填括号方案数,发现可以倒着转移。

同时发现每段 \(f_i\) 中权值在 \([1,k]\) 中的位置是 \(O(1)\) 级别的,可以维护出满足条件的区间转移。

复杂度 \(O(n\times ?)\)

T2

题意:\(T\le 3\times 10^5\) 组询问有六个数 \(a,b,c,x,y,z\),表示你有三个背包容量为 \(a,b,c\),有三种物品,大小是 \(x\le y\le z\)\(z-y=y-x\),要求能做多少轮操作,每一轮操作是同时把三种物品丢进三个背包里,每个背包必须且只能丢一种。

考虑二分答案,然后把三个背包都减掉轮数乘上 \(x\),然后除掉公差 \(k\),然后变成了有 \(k\)\(1,2\) 要放到背包里,且每个背包最多放 \(k\) 个。

这个问题就是经典 CF div2 题了。可以乱做然后奇怪证明。

T3

题意:有一个 \(n\) 边多边形,给出它的一个三角剖分,\(m\) 次操作从把一条边的中点到另一条边的中点上顺序交到的剖线的权值分别加上 \(1,2,....,k\)

题解:考虑三角剖分除了端点处不会相交,只有包含和不交关系,所以先把环看成链,然后加入一条从 \(1\)\(n\) 的边,则可以根据包含关系(最小的包含它的区间作为父亲)构造树,然后发现交线加等差数列的操作变成了树上这两条边对应的节点的路径上除了 LCA 和它们自己加等差数列。所以树上二阶差分。

T4

题意:每个人有四种权值。要求你选三个人,他们的权值是每种权值最大值之和,且三个人中每个人必须有一个最大。保证每种权值互不相同。\(n\le 4\times 10^5\)

发现如果当前的四个最大值对应的人互不相同就可以直接枚举选哪个,另一个人可以也直接枚举。

如果当前出现了三料甚至四料冠军,那么没有人会和他组队,丢掉即可。

于是剩下双料冠军,发现如果有一个双料冠军和两个单料冠军就做完了,否则不断取出这双料的第 \(i\) 大然后用另一个最大的非双料即可。

P2291

枚举次数,次数大于 2 的显然可以暴力枚举,次数等于 2 的需要做一个区间筛,筛出 \([\sqrt{n},\sqrt{n}+V]\) 的质数(用埃氏筛),\(v\) 根据实际情况每 \(ln n\) 个数就有一个质数,大概取 \(3\times 10^6\) 即可。当然次数大的也需要多枚举一点质数防止寄掉。

CF1553G

考虑答案最多为2,因为可以 S 建一个,T 建一个新点,两个必然都是偶数。

于是先对于每个质因数建一个新点,然后求出连通块,并枚举每一个 $a_i $ 看哪两个能一次操作合并,之后就可以判了。

CF1699D

考虑一段区间不存在绝对众数(出现次数大于一半)时可以全部删掉,然后可以直接设 \(f_{i,j},g_i\) 转移。

CF1622F

答案一定不小于 \(n-3\)。对于偶数,最多同时删掉 \(2,\frac{n}{2}\),对于奇数,把自己删掉即可。

于是变成了判断 \(n,n-1,n-2\)

首先如何快速判断完全平方数?给每个质因子随一个哈希值,一个数的所有质因子的哈希值异或和是 0 则大概率是完全平方数。

然后你枚举整个序列看能不能一个都不删,枚举删一个,然后用桶存下删一个的值枚举删另一个能不能行即可。

根据实现(如果随机的哈希值比较大用 map,小的话开数组)复杂度 \(O(n)-O(n\log n)\)

P7530

扫描线,线段树维护以这个节点作为左端点是否合法和以它作为左端点的合法的中间点的合法方案数,则每次扫一个节点我们要计算这三部分。然后我懒得写了。

UOJ529

你分成三组打包出售恶臭,具体的,分成 114,5,14 来卖,然后对于 5 是正确的,中肯的,切中肯綮的,对于 114 和 14,你把 4 钦定成恶 4 和臭 4,然后发现你确定了恶臭 4 之后,可以臭 4 左边选最近能选的,恶 4 左边任选两个能选的,然后打包出售。但是发现这不够dalao~,为什么呢,你的恶臭无法确定,但是发现你确定一个恶 4 的上界然后从左往右一个一个一个扫,能确定成恶的就确定下来然后就做完了。我说的是正确的,中肯的,切中肯綮的。

Day7

AGC058D

设题目中不能出现的段是上升段(模意义下),你钦定 \(k\) 个这样的极长上升段(保证每个段的上一个位置不能被加入),然后剩下的位置随便填。

然后特判掉有一个段在开头的情况,然后对答案乘上 \((-1)^k\) 即可。

AGC035D

posted @ 2022-11-15 16:32  infinities  阅读(35)  评论(0编辑  收藏  举报