2021.8做题记录

xsy1491A

注意到 \(2^{m-|S|}\) 本质上是凸包内部的点任选,这相当于我们任选一些点,这些点会构成一个凸包,我们这个时候就可以把剩下的点算到这个凸包上的答案上
所以答案就是 \(2^n-\binom{n}{2}-n-1\)
但是注意到还可能有三点共线的情况,对于一条上面有 \(l\) 个点的直线,我们要减去 \(2^l-\binom{l}{2}-l-1\) 的贡献
\(\mathcal O(n^2\log n)\)

code

xsy1491B

显然先把图建出来
假设我们现在想让 \(x\) 活下去,那么所有 \((x,y)\)\(y\) 都要为 \(x\) 而死,设 \(y\) 死的时间为 \(t\)
那么所有 \((y,z)\) 且时间 \(t_0<t\)\(z\) 都要为 \(y\) 而献身
以此类推,我们可以知道,如果 \(x\) 想活,哪些人必须为他死
如果 \(x,y\) 想同时活,那么他们两个的献身集合必须没有交集
\(\mathcal O(n^3+nm)\)

code

CF1036G

考虑对于一个闭合真子图,如果他的汇点比源点个数少,我们只要把所有汇点连到这里面任意的源点里,他就被锁在这里面了,显然不强联通
所以我们枚举这个闭合子图的源点集合,算出汇点集合,计算 popcount 即可
\(\mathcal O(n^2+nm+C2^C)\)
code

CF1453F Even Harder

难度主要在设计状态
如果我们这条路径选了 \(i,j(j<i)\),并且 \(i,j\) 中间不再走别的,那么我们需要满足一些条件
\(\forall k\in(j,i),k+a_k<i\)
如果有这样的,我们把这样的点变成 0 显然是最优的
但是注意,如果 \(j\) 是从 \(k\) 跳过来的,那么 \(k+a_k<i\) 也要成立
有了这两个条件,我们就可以设计 dp 状态了

\(f[i][j]\) 表示现在在\(i\),上一步最多跳到 \(j\),那么有转移

\(f[i][j+a_j]=\min\{f[j][i-1]+calc(j,i-1,i)\}\)
要对 \(f\) 做前缀 min

code

CF1430G Yet Another DAG Problem

sol.1
把边权在 \(a_v\) 减去,在 \(a_u\) 加上
\(f[i][S]\) 表示 \(S\) 里面的数的权值都在 \(1\sim i\),现在枚举 \(i+1\) 的数有那些,复杂度 \(\mathcal O(n3^n)\)
考虑优化,不难想到优化方向是每次新加一个点,但是这个点有可能和之前加入的一个点有边但是我们不知道可不可以
所以我们可以按照拓扑序从大往小选点,这样如果我们选到了一个 \(v\),就一定不会把 \(v\) 的出边和 \(v\) 算到同一个权值
为了方便输出用 \(f[i][j][S]\) 表示现在放的权值为 \(i\),上一个放的拓扑序为 \(j\),集合为 \(S\)
\(\mathcal O(n^22^n)\)
code
sol.2
考虑每次放一些点 \(S\),对于任意的 \((u,v) u\in S,v\in \overline S\),会在放 \(i,i+1\) 的时候算入贡献
所以我们要对于每一个 \(S\) 预处理上面那些边的权值之和,然后直接枚举子集就可以了
\(\mathcal O(m2^n+3^n)\)

CF513G3 Inversions problem

一道非常有价值的好题。
首先看到期望题,把每一对数的贡献拆开来算。
我们用 \(f[t][i][j]\) 表示经过 \(t\) 次交换后 \(a_i>a_j\) 的概率。
答案就是 \(\sum f[k][i][j]\times[i<j]\)
我们考虑枚举反转区间,这样我们就得到了一个 \(\mathcal O(n^4k)\) 的转移。
转移的时候反转区间分四种(下面我们默认 \(i<j\)

  • 不包括 \(i,j\),这时考虑左右端点在 \([1,i),(i,j),(j,n]\) 的方案数直接组合数计算即可,\(\mathcal O(1)\)
  • 只包括 \(i\),我们可以枚举 \(i\) 最后变到的位置 \(p\),这样我们就知道反转区间的对称中心是哪里,进一步不难算出方案数。
  • 只包括 \(j\),同上。
  • 同时包括 \(i,j\),这样的话翻转完之后 \(i^\prime-j^\prime=j-i\),所以我们可以让 \(i^\prime=p,j^\prime=p+i-j\),同样可以算出转移的方案数。
    这样我们得到了一种 \(\mathcal O(n^3k)\) 的做法。
    从让输出 double 可以看出其实 \(k=10^9\) 是假的。
    对于这道题 \(k\) 设成 \(\min(k,1000)\) 就可以通过了。
    但是 \(\mathcal O(n^3\min(k,1000))\) 也不足以通过此题(虽然好像能跑过)。
    我们需要优化转移的过程,其实后三种情况本质上是类似的,下面以第二类只包括 \(i\) 的转移情况为例:
    \(p<j\) 的时候,有 \(f[t][i][j]+=f[t-1][i][p]\times \min(p-i,n-j+1)\)
    \(p\geq j\) 的时候,有 \(f[t][i][j]+=f[t-1][i][p]\times \min(j-i,n-p+1)\)
    我们观察后面乘的那个倍率,我们发现两个 min 里面的断点是相同的。
    在纸上画一画他的图像(其实猜也能猜到),他的点值是长成这个样子的:

\[0,0,0,\cdots0,1,2,\cdots,x-1,x,x,\cdots,x,x-1\cdots,2,1,0,\cdots,0,0,0 \]

接下来的问题就是有两个点值多项式 \(f(x),g(x)\),其中 \(g(x)\) 就是上面那坨东西,现在要快速求 \(f(x)g(x)\) 的点值之和。
考虑对于 \(g(x)\) 从后往前差分,我们得到的应该是

\[0,0,0,\cdots,-1,-1,-1,\cdots,0,0,0\cdots,1,1,1,\cdots,0,0,0 \]

发现如果 \(g(x)\) 长成上面这个样子我们可以直接预处理 \(f(x)\) 的前缀和来解决。
因为差分是前缀和的逆运算,所以在原问题中,我们直接预处理 \(f(x)\)二阶前缀和即可。
一般的,设 \(s_2[i]\)\(f(x)\) 的二阶前缀和,

\[g(x)=0,0,0(a),\cdots0,1,2,\cdots,x-1,x(b),x,\cdots,x(c),x-1\cdots,2,1(d),0,\cdots,0,0,0 \]

的答案是 \(s_2[d]-s_2[c-1]-s_2[b-1]+s_2[a-1]\)
这样我们就可以 \(\mathcal O(1)\) 转移第二类区间了。


对于第三类区间,同理。
对于第四类区间,我们预处理 \(i-j\) 相同的点的二阶前缀和。
\(\mathcal O(n^2\min(k,1000))\)
代码还是非常美观的
code

xsy1493B

打表出来发现如果有奇数个偶数,那么先手必胜
考虑如果有偶数个偶数的情况,如果偶数的个数不是 \(n-1\),那么先手怎么改都会给后手一个奇数个偶数的情况,此时必败
否则后手一定会去改那唯一一个奇数,递归下去即可
\(\mathcal O(n\log a_i)\)

code

AT2267 [AGC008E] Next or Nextnext

设连边 \((i,p_i)\) 的图为 \(G_1\),连边 \((i,a_i)\) 的图为 \(G_2\)

显然 \(G_1\) 是若干个环。
对于 \(G_1\) 上的一个环,他在 \(G_2\) 里有四种情况:

  • 如果环上的点满足 \(p_i=a_i\),在 \(G_2\) 上有一个和他一模一样的环
  • 如果环上的点满足 \(p_{p_i}=a_i\),且环长为奇数,在 \(G_2\) 上有一个和他点数相同,形态不同的环
  • 如果环上的点满足 \(p_{p_i}=a_i\),且环长为偶数,在 \(G_2\) 上有两个点数是他的一半的环
  • 如果环上的点两种点都有,那么这个环在 \(G_2\) 上是一个内向基环树

现在知道 \(G_2\),问 \(G_1\) 的方案数。
环和基环树是独立的,先看环,不同长度的环之间也是独立的。
设有 \(cnt\) 个长度为 \(x\) 的环,枚举有 \(2i\) 个被拼到了一起。
先选出这 \(2_i\) 个环,\(\binom{cnt}{2i}\),从 \(2i\) 个环里选 \(i\) 个放到左边,\(\binom{2i}{i}\),然后做匹配,\(i!\),注意到每条边可以左右翻转一下,所以要除以 \(2^i\)
对于每两个环,有 \(x\) 种拼法,还要乘上 \(x^i\)
对于剩下的环,如果 \(x\) 是偶数,每个都只能不动,否则每个有两个拼法。

考虑基环树,环上每个点的度数必须 \(\leq 2\),环上挂的必须是链,并且这个链拍扁了之后必须不能超过上一个有链的位置,如果刚刚好够到,方案为 \(1\),否则为 \(2\)
这样就做完了

code

xsy1498A

每个上升数可以表示成 \(9\) 个全是 \(1\) 的数之和,一个长度为 \(a_i-1\) 的全是 1 的数是 \(\frac{10^a_i-1}{9}\)
所以 \(\sum_{i=1}^{9k}\frac{10^{a_i}-1}{9}=n\)
\(\sum_{i=1}^{9k}10^{a_i}=9n+9k\)
相当于 \(9n+9k\) 的每位数字之和要大于等于 \(9k\)
枚举 \(k\),每次加法均摊下来是 \(\mathcal O(1)\)

code

CF1554E You

相当于给每条边定向,\(a_i\) 就是 \(i\) 的入度。
所以 \(\{a_i\}\) 一共有 \(2^{n-1}\)
考虑 \(k=1\) 的不好算,算 \(k>1\)
发现 \(k>1\) 时,所有叶子节点必须指向父亲,而通过这一层的我们可以算出上一层的边的指向,所以如果有方案,那么方案是唯一的。
而且 \(k\) 显然必须是 \(n-1\) 的约数,所以我们枚举 \(n-1\) 的约数在做一遍就好了。
但是注意即使 \(k\) 可以也不代表 \(k\) 真的可以,因为他的 gcd 可能是 \(k\) 的倍数。

code

考虑容斥
但是直接容斥是 \(2^2n\)
考虑优化一下,我们枚举对角线选取的情况和行选取的情况
现在对于第 \(i\) 列,我们用 \(p\) 表示这一列目前没有强制选的 \(p\) 的 prod
对于每一列,如果没选,对容斥的贡献是 \(1\),如果选了,对容斥的贡献是 \(-p\),总体上就是每一列的 \(1-p\) 乘起来

code

CF1107E

做法显然是区间 dp。
这题的难度主要在于设计状态。
我们观察他可能会把中间的给消掉然后拼一个别的过来,所以用 \(f[i][j][k]\) 表示 \([i,j]\) 后面有 \(k\) 个和 \(j\) 颜色相同的现在要和 \(j\) 一起消掉。
两种转移:

  • 消掉一个后缀,\(f[i][j-1][0]+a[k+1]\to f[i][j][k]\)
  • 对于一个 \(s_x=s_j\),消掉 \((x,j)\),把后面的拼到 \(x\) 后面和他一起删掉 \(f[i][x][k+1]+f[x+1][j-1][0]\to f[i][j][k]\)

\(\mathcal O(n^4)\)

code

P3526 [POI2011]OKR-Periodicity

首先,我们知道 Period 和 Border 是等价的。
我们先把所有 Border 求出来,问题变成了构造一个字符串使得 Border 集合和给定的字符串的 Border 集合相等。
我们考虑一个一个满足,对于给定的字符串的 Border 序列,设其为 \(\{a_m\}\)
首先构造一个满足 \(a_1\) 同时字典序最小的,不难发现如果 \(a_1=1\),就是 0,否则是一串 0 加一个 1
考虑 \(a_{i-1}\) 变成 \(a_i\),此时有个重要的条件就是 \(a_{i-1}\)\(a_i\) 的最长 Border
分两种情况

  • \(2a_{i-1}\geq a_i\),此时直接把 \(a_{i-1}\) 的后 \(a_i-a_{i-1}\) 位补过来就可以了
  • \(2a_{i-1}<a_i\),此时中间需要填上一些东西,最优肯定是填 00000,但是这样有可能会出现一个更长的但是不应该出现的 Border,所以我们把最后一个 0 换成 1 就可以了,可以证明这样一定是可以的

\(T(n)=T(\frac{n}{2})+O(n)\)
复杂度为 \(\mathcal O(n)\)
code

P3349 [ZJOI2016]小星星

首先考虑 dp,用 \(f[u][j][S]\) 表示 \(u\)\(j\) ,子树里已经已经放的点的集合为 \(S\)
然后可以枚举子集转移做到 \(\mathcal O(n^33^n)\)
考虑优化,注意到这种子集 dp 的一种优化方式是考虑容斥。
因为我们的 \(S\) 是为了限制不选重复,所以我们直接 \(2^n\) 枚举哪些点是可以选的进行容斥即可
复杂度变成 \(\mathcal O(n^32^n)\)

code

CF1556F Sports Betting

考虑枚举哪些人最后赢了,设为 \(S_1\),设 \(U\ xor\ S_1=S_2\)
\(S_1,S_2\) 之间的边必须是 \(S_1\)
\(S_1\) 里面的点必须互相可达
难点在第二个
\(f[S]\) 表示 \(S\) 里面的点相互可达的概率
考虑容斥,计算不互相可达的概率,也就是存在 \(S\) 的一个子集 \(S_1\)\(S_1\)\(S_2=S\ xor\ S_1\) 之间的边全部定向
发现这和第一个是一样的
直接枚举子集转移即可

\(\mathcal O(n3^n)\)

code

[CF1556D]

\((a|b)+(a\&b)=a+b\)
code

CF1037F Maximum Reduction

考虑最后选的区间长度一定是 \(k,2k-1,3k-2,4k-3,\cdots\)
我们可以枚举答案,发现对于不同的区间长度 \(p\),左端点和右端点的范围分别只有两种情况
把区间拆成三段来做就可以了

code

posted @ 2021-08-14 16:38  YuukiYumesaki  阅读(96)  评论(0编辑  收藏  举报