Cry_For_theMoon  

1. Good Subsegments

这个已经是典中典题了。

首先考虑一个段合法等价于 \(mx - mn = r-l\),也就是 \(mx-mn-r+l = 0\),而且注意到 \(mx-mn-r+l\ge 0\),所以如果我们全局询问的话,那就是扫描线维护,然后维护一下全局的最小值以及最小值个数就行了。

然后区间的子区间计数就考虑套维护历史信息的 trick,也就是我们还是维护扫描线的过程。操作是区间加。

然后询问的东西实质上有点牛魔的:相当于给出一个区间 \([l,r]\),首先要求这些位置的历史最小值的 \(\min\),设为 \(x\),还要求出每个位置历史值 \(=x\) 的次数和。

这个东西手搓了一下竟然自己手搓出来了:考虑对每个位置维护一个三元组 \((min,cnt,sum)\),表示该位置的历史最小值,以及历史最小值个数,还有当前的值,那么原序列上的加法(对应这个三元组的乘法)是容易的:\(+a\) 等价于乘上 \((a,1,a)\);但是我们用线段树的话,首先就需要定义加法,然后还需要满足分配律。

加法的话比较牛魔,先不考虑分配律,那就是 \(\min\) 是两个人的 \(\min\) 取最小值;然后 \(cnt\) 跟着算,然后 \(\sum\) 也得取 \(\min\)。但是发现他好像不满足分配律:两个一样的三元组,合并起来的话以后都是要当两份算的,但是没有体现出来。所以还要记录一下有多少个位置他的 \(sum = \min sum\),这个四元组的加法乘法满足分配律,然后就可以 seg 打 lazy 维护了。

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

记录

2. Ping-Pong

我咋感觉这个非常难啊??

题目的约束告诉我们如果 \(A\) 严格包含 \(B\)\(B\) 能到达 \(A\);如果相交不包含则可以互相到达。

如果只有第二类关系,则维护可达性是非常容易的,可以用 dsu 维护,在线段树上加速:注意到区间单调增的限制,所以加入 \((l,r)\) 的时候一定没有区间包含他;我们只用算多少区间覆盖了 \((l-1,l+1)\)\((r-1,r+1)\) 这两条线段(二者选其一,且一个线段最多也只满足其一)就好了,然后就可以用 seg 辅助维护。

第一类关系就很复杂感觉,但有这样一个性质:若 \(A\) 严格包含 \(B\)(实际上本题没有相等的区间),则 \(A\) 所在的连通块一定包含 \(B\) 所在的连通块。

根据这个性质我们只会在开始的时候走最多一次第一类单向边,他也等价于 check 终点的所在连通块区间是否包含起点所在的连通块区间(注意这里非严格)。

但是这个非常坑啊,注意到 observation 的表述是包含,而非严格包含;虽然给出的区间没有相等的,但是可能两个不同的连通块,他们代表的区间范围是完全相等的。

可以发现这种情况下 \(A\) 不能到 \(B\) 当且仅当 \(A\) 本身构成一个连通块,且其等于 \(B\),判掉就好了。

记录

3. Vladislav and a Great Legend

\(x^k\) 用组合意义拆开然后变成选 \(k\) 条边,且选择一个合法的点集,也就是对于每条边:两端的连通块各有一个点,其实也就是子树内和子树外。

那就要做树上背包状物,并且带两个 \(0/1\),一个记录子树内有无选点,一个记录是否还要求子树外选点,合并方式和树上背包一样。

这样有个问题,因为组合意义的话,一条边是可以出现多次的,那还要枚举一条边出现的次数。

其实可以强制选一个不可重集 \(S\),那么 \(|S|\) 就可能 \(\lt k\) 了,然后需要计算把这个 \(S\) 扩张成大小为 \(k\) 的可重集的方案数(且有序),显然只和 \(|S|\) 有关,那就可以 dp 一手。

其实这个东西就是 \(x^k\) 展开成斯特林数那玩意,两者是殊途同归的。

时间复杂度 \(O(nk+k^2)\)

记录

4. Move by Prime

总感觉很久以前 Sept 给大家看过这个题,当时口胡完一下就跑了呃呃。

考虑每个质因数的贡献是独立的,然后考虑一个序列就是中位数。

然后考虑一个序列的贡献,如果我们强制令 \(M=\lceil \frac{n}{2} \rceil\) 的位置是中位数,那其实就是,如果偶数的话:前 \(M\) 个位置贡献是负的,后 \(n-M\) 个位置贡献是正的(至于中位数恰好抵消了就),如果奇数的话就是前后 \(M-1\) 个分别贡献负/正。

那其实可以这样避免分讨:就是考虑前面的个数 \(a\) 和后面的个数 \(b\),如果 \(a\lt b\) 就贡献负,否则 \(a\gt b\) 的话就贡献正。

那就是设前面有 \(x\) 个后面有 \(y\) 个(注意 \(x+y=n-1\))则贡献为负的数量是 \(\sum_{a=1}^{x}\sum_{b=a+1}^{y}\dbinom{x}{a}\dbinom{y}{b}\),后半部分差不多的。

枚举 \(d=y-x\),则变成 \(\sum_{d\ge 1}\sum_{i}\dbinom{x}{i}\dbinom{y}{d+i}=\sum_{d\ge 1}\dbinom{x+y=n-1}{y-d}\)

所以对于一个人可以 \(O(1)\) 算,预处理组合数前缀和就好了;注意到对于质因子出现次数相同的,可以合并到一起统一计算,因此时间复杂度就变成了 \(O(n\omega)\),反正很小。

记录

5. Centroid Probabilities

感觉 Half Queen 比这个难呃呃

\(m = \lceil \frac{n}{2} \rceil\),则一个必要条件是 \(sz_i \ge m\),这样子树外的点数就对了,那么很容易看出 \(i\le m\)

因此考虑求出 \(f_i\) 表示全局有多少棵树是满足 \(sz_i \ge m\) 的,考虑如果我们知道 \(f_i\) 如何求 \(ans\)

我们只需要去掉有儿子是 \(\ge m\) 的情况即可,而且这样的儿子只有一个。我们钦定 \(j\gt i\) 是这个儿子,那注意到不是所有的 \(f_j\) 都要被减掉,因为有时候 \(j\) 不是 \(i\) 的儿子,所以是减掉 \(\frac{f_j}{j-1}\)。那么很容易 \(O(n)\) 做到 \(f\rightarrow ans\)

现在考虑求 \(f_i\),它看上去会比想象的困难,因为我们得枚举子树大小 \(a\)(不含 \(i\) 本身),然后从 \(n-i\) 个点里选取 \(a\) 个,然后考虑这 \(a\) 个点选父亲有 \(a!\) 种方法,考虑 \(i\) 和剩下的点,注意到点 \(i\) 是特殊的,因为此时我们钦定它是叶子,那点 \(i\)\((i-1)\) 种选择父亲的方案(这里需要特判 \(i=1\)),然后剩下的 \(n-a-1\) 个点实质上有 \((n-a-2)!\) 种方式,因此得到:

\[f_i = \sum_{a=m-1}^{n-i}\dbinom{n-i}{a}a!(i-1)(n-a-2)! \]

注意 \((i-1)\) 这里没有阶乘符号。

对于组合数和很多阶乘组合的式子,就可以考虑全部拆开并且提取公因式:

\[=\sum_{a=m-1}^{n-i}\frac{(n-i)!}{(n-i-a)!}(i-1)(n-a-2)! \\ =(i-1)(n-i)!\sum_{a=m-1}^{n-i}\frac{(n-a-2)!}{(n-i-a)!} \]

注意到里面的差是定值:\((n-a-2) - (n-i-a) = i-2\),因此可以变成:

\[(i-1)(n-i)!(i-2)!\sum_{a=m-1}^{n-i}\dbinom{n-a-2}{i-2} \]

里面不是我们上指标求和吗?做完了。

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

记录

6. Expected Value Again

这个题很恐怖啊,但是他感觉是比 ISIJ T2 弱的,所以 ISIJ T2 怎么做????

用组合意义拆开,相当于随便枚举两个 \(1\le i,j\le n-1\),要求串同时有长度为 \(i,j\) 的周期,我们想知道有多少个等价类。

\(n\) 足够大的时候,可以看出答案就为 \(\gcd(i,j)\)。事实上他等价于这个事情:我们只考虑 \(\bmod i\) 的剩余系,然后所有 \(\le n-j\) 的数 \(x\) 会和 \(x+j\) 连边,因此如果 \(i+j \le n\),那一定每个点都有一个连边(前 \(i\) 个点),那根据经典数论结论我们知道有 \(\gcd\) 个大小一样的环啊啊啊啊。

我去,这不是我们弱周期引理吗,还真是。但是弱周期引理没告诉我 \(i+j\gt n\) 怎么办啊??

考虑因为我们知道最后连完了 \(i\) 条边那每个连通块也是环,我们现在只能连一些前缀的边;如果每个连通块最后是树,那其实很简单,我们加上 \((i+j-n)\) 就行,因为每少一条边就多一个连通块。

现在有环,所以我们为每个环钦定一条特殊边,当删去这条特殊边的时候连通块数量不增加,显然这条边就是那个环上编号最大的人啊啊啊。也就是其实最后 \(\gcd\) 个人都是特殊点,他们连出去的边就算不被加上去,那也不会让连通块大小数量变化。

所以应该是加上 \(\max\{0,i+j-n-gcd\}\),此时答案是 \(\gcd + \max\{0,i+j-n-gcd\}\) 呃呃。

那不难看出这个式子其实等价于 \(\max\{\gcd,i+j-n\}\),而且也能推广到 \(i+j\le n\) 的时候,这个时候 \(i+j-n-gcd\) 一定负的了...

所以我们现在只用求 \(\sum_{1\le i,j\lt n}k^{\max\{\gcd(i,j),i+j-n\}}\) 了......

到这里其实还是挺烦的,因为就算是去掉那个 \(\max\) 都挺复杂的。

后面的做法很神:我们不妨先计算 \(\sum_{i,j}k^{i+j-n}\),然后对于 \(gcd\gt i+j-n\)\((i,j)\),把答案修正回来。

第一部分太容易了,考虑第二部分,枚举 \(\gcd = v\),然后令 \(l_v = \lfloor \frac{n-1}{v} \rfloor\),则要求 \(\sum_{i,j\le l_v}[\gcd(i,j)=1][v \gt v(i+j)-n](k^{v} - k^{v(i+j)-n})\)

通过第二个艾弗森约定可以推出 \(s = i+j \le 1 + \lfloor \frac{n-1}{v} \rfloor = 1+l_v\),然后我们转而枚举 \(s\)(因为除了 \(\gcd(i,j)=1\) 以外其它的都只和 \(s\) 有关),又因为 \(\gcd(i,j)=\gcd(i,i+j)\),所以 \(\gcd(i,j)=1\) 也就等价为 \(\gcd(i,s)=1\),而且因为 \(s\) 的上界缘故所以不用担心 \(i,j\) 超过 \(l_v\)

那就是 \(\sum_{2\le s\le l_v}\phi(s)(k^v - k^{vs-n})\)

把括号拆开的话,\(k^v\) 这里很容易,只不过是一个 \(\phi\) 函数前缀和罢了,但是第二部分必须枚举所有的 \(s\),那时间复杂度好像又不对了啊啊啊

很神的一点是我们不妨最开始只对 \(i+j-n\ge 0\) 的部分加上去,因为我们知道如果 \(i+j-n \lt 0\) 则必定取 \(\gcd(i,j)=0\),这样第二部分减去的时候只用考虑 \(vs-n\ge 0\) 的情况也就是 \(s\ge \lfloor \frac{n}{v} \rfloor\)。注意到这个下届和上界 \(l_v+1\) 中间只有 \(O(1)\) 个点,因此时间复杂度变成了 \(O(n)\),啊?

记录

7. Coloration

好神的题?怎么 csy 一分钟就会了?????

根据瓶颈路的限制我们想到建出 MST,更进一步不妨建出重构树。我们称边为方点,原图中的点为圆点。

注意到,根据题目的描述,重构树形态唯一,然后说如果一条边不在树上则 \(T=\empty\),否则它的 \(T\) 就是子树内的,不小于它的圆点个数,很容易计算出。

考虑每个圆点会向上贡献一段方点,然后不再贡献(因为重构树的方点点权向上递增),这是一个很好的性质。

考虑我们先让所有人变成黑色,然后每个方点实际上要求它的 \(T\) 中变成白色点的数量在一个 \([L_i,R_i]\) 之间。

考虑常规的 dp 很难满足这个约束,因为不同的圆点不等价,所以不能只简单地记录当前集合的内的白点数量之类的。

考虑用费用流去描述这个东西,因为有一个 \([L_i,R_i]\),所以可以猜测到这大概是上下界费用流。

给重构树上每个方点拆点,然后要求流量在 \([L_i,R_i]\) 之间,每个方点的 out 向父亲的 in 连边代表圆点的向上传递。

圆点传递到一个位置就不走了,怎么解决?

如果一个圆点 \(u\) 走到 \(x\) 的时候出现了 \(v_u \lt v_x\),那就从 \(x\) 的 in 向 \(u\) 连回去一条边,流量为 \(1\)

然后 \(u\) 向父亲连流量为 \(1\) 的边,费用为 \(a_i - b_i\)

这样的话,我们跑上下界最小费用循环流就好了。

有个问题,这样有负环啊?

然后其实带负环的 MCMF 也能求的,如果有一条边的 \(f\) 是负的就流满然后建反向边。最后建超级源汇,像上下界那样连,跑一遍此时的 MCMF,然后此时的图就不带负环了,此时跑原图 \(s\rightarrow t\) 的 MCMF 即可。

记录

8. 字符串重排

先考虑什么样子的排列是满足第一问的:我们建立 trie,则 trie 上的 dfs 序最优,但不一定非要是 dfs 序:因为有前缀关系存在,而且我们看到有一个部分分就是没有前缀。

考虑后面两问就是倒着判断限制,能加入就加入。

对 trie 树做这样一个事情:对每个终止节点再开一个儿子,把终止节点放到这个位置。则我们解决了前缀的问题,这个时候 dfs 序和最优排列首先是等价的。

然后考虑加入限制相当于要求一个节点在另一个节点前面。考虑也就是对若干节点,要求他是父亲的所有儿子里第一个 / 最后一个遍历到的;然后对于 lca 处,还钦定了两个儿子的紧密遍历顺序。

我们考虑把只有一个儿子的点缩掉,容易发现这个时候深度不超过 \(O(\sqrt L)\),那考虑完全可以暴力去 check 路径上每个点了。

每个点用 dsu 维护所有儿子构成的若干条链式关系,并且维护每条链的开头结尾。

但有一个很坑的点就是要判这种情况:就是起点和终点都在一条链上,但这条链的以外还有别的点。

时间复杂度 \(O(m\sqrt L\alpha)\),但其实跑得飞快。

记录

9. Guess the number

考虑假设我们知道答案落在 \([l,r]\),则我们最多只能问 \(l\) 个数。

然后可以设 \(f(i,l,r)\) 表示还剩 \(i\) 次操作,我们知道答案落在 \([l,r]\) 的最优策略。

但这样没必要,考虑我们可以设 \(f(i,l)\) 表示左端点为 \(l\) 的时候,能保证问出的最长区间大小;那我们只需要利用 \(f(i-1)\) 的信息就能确定策略。

注意到 \(l\ge 10^4\) 的全部都是相同的,所以第二维开到 \(10^4\) 就行了。

转移的时候注意到当我们跑到 \(l\ge 10^4\) 的时候后面都是在重复累加区间长度,然后这个东西增长非常恐怖,真的是 \(5\) 次就能问出来了啊啊啊。

记录

10. AB Tree

神题。

注意到答案的下界是深度最大值,设为 \(d\)

我们要求最优化答案,但你会发现判断答案是否为 \(d\) 都是一个不弱于背包的问题:这要求每层填相同的字符,然后我们要对其做背包。

经典物品种类不超过 \(O(\sqrt n)\) 的多重背包。这里有一个严格 \(O(n\sqrt n)\) 的方法:用类似完全背包的方式跑,然后记录当前这个值,为了达到他,最少要用几个当前种类的物品就行了,所有只判断可达性的多重背包都能用这个直接做到 \(O(nV)\),和数目无关。

但显然我们可以构造出来答案大于 \(d\) 的数据;现在变得非常棘手了。

可以这样去想:首先我们有一种看上去比较优秀的构造方式,就是从上往下能填 \(A\) 就填 \(A\),否则就填 \(B\)。这样我们只有一层会混用 \(A,B\) 啊。

那我们注意到,如果说这一层,填 \(A\) 和填 \(B\) 的节点,分别考虑他们向下的最大深度,设为 \(x\)\(y\),则答案就是 \(dep+x+y+1\)\(dep\) 是当前层的深度。

那这个其实就是 \(d + \min\{x,y\}\),如果我们能让 \(\min\{x,y\}=0\),也就是说让 \(A\) 只去填这一层的叶子,或者说让 \(B\) 只去填这一层的叶子(不一定填满,但不能出现在这一层的非叶子节点上),那就可以把答案构造到 \(\le d+1\) 的范围,这就和前面对上了。

但我们发现,按照我们的那个策略,其实是很不灵活的,因为这个交界的层是完全被确定的,只要这一层的叶子和非叶子数量分布不如我们理想的那样那就寄了。

但是我们只利用到:其他层同层节点颜色相同这样一个性质。那考虑从上往下染色,设这一层有 \(x\) 个非叶子节点,\(y\) 个叶子节点。可以发现总有一种颜色可以填满 \(x\) 个非叶子节点;如果这种颜色还够填 \(y\) 个叶子,那就填这 \(y\) 个;否则这种颜色的剩余的全部去填 \(y\) 个叶子肯定还有剩余的;此时我们把剩下的叶子,以及深度更大的点全部换成另一种颜色就好了。

这样我们确实构造出了 \(ans \le d+1\) 的答案,整个问题的瓶颈就在于最开始的背包,复杂度 \(O(n\sqrt n)\)

记录

11. Shrinking Tree

这个题有点神。

考虑枚举每个点算答案,然后重新定根。

我们还是把删边这种动态的事情变成静态的:给每个边分配一个 label 表示它是第几次被删的。

考虑根和别人合并一次,它留下的概率就会除二。根和它的儿子肯定都会合并,但如果是一条链,我们也不止合并一次啊。

不难发现:一个点 \(u\)\(u\neq rt\))会被合并,当且仅当它和父亲的边,这个 label 比根链上其它的 label 都大。

那就变成了一个可以树形 dp 的东西:我们直接设 \(dp(i,j)\) 表示 \(i\) 的子树内,有 \(j\) 个这样的点。但这样不能转移,我们再加入一个 \(k\),表示根链上的 \(\max\) 它的 label 比子树内第 \(k\) 小的要大,比第 \(k+1\) 大的要小。则 \(dp(rt,...,0)\) 就是答案。

转移的时候我们先合并儿子,这个就是两个组合数作为系数;然后再考虑 \(i \rightarrow fa\) 的边,枚举它的 rk 就行了。

这样做一次是 \(O(n^4)\) 的,树形背包部分 \(O(n^2)\),但是瓶颈反而在于考虑到父亲的那条边。

首先注意到我们不需要记录 \(j\),每次 \(j\) 改变的时候把 \(2\) 除了就行;这样就是每次 \(O(n^3)\) 了,至于转移其实可以前缀和优化一下。

这样算出全部答案也是 \(O(n^3)\) 的。

记录

12. Product of Sorting Powers

显然可以莫,长得还很像 WC2022T2,可以回滚莫队那种。

但是这里没救,因为我们算两个数的贡献要快速幂,变成 \(O(n\sqrt m\log V)\) 了,直接 gg。

考虑我们能算出离散对数就好做了,但是怎么对 \(10^6\) 个数同时算???

如果把块长开大点也不行,空间限制很严格。

科技 \(1\):对 \(1\sim n\) 同时算他们的离散对数:

我们不需要做 \(n\) 次 BSGS,只需要对每个质数位置做 BSGS 就好了,因为 \(f(xy)=f(x)+f(y)\),而且可以把块长适当开大,本题开到 \(10^6\) 差不多。注意 BSGS 一定要用哈希表,不然多的这个 \(\log\) 很致命。虽然本地 gp_hash_table 很快,但是好像 hdu 对这个太不友好了,换成手写 hash 表才过。

科技 \(2\):单次 \(O(\log a)\) 算一个数的离散对数。

首先我们用上面的方法处理出 \(1\sim \sqrt{p}+1\) 的离散对数,然后对于一个 \(x\),令 \(p = qx + r\),其中 \(r\) 是一个 \((0,x)\) 的数(因为 \(p\) 质数所以不会为 \(0\))。

那么 \(qx\)\(-r\)\(p\) 意义下同余,所以他们的离散对数模 \(\phi(p)\) 意义下同余,那只用算 \(\log(-r) - \log(q)\),而注意到 \(q\le \sqrt{p}+1\)

\(\log(-r)\) 就是 \(\log(p-1) + \log r\),可以预处理出 \(\log(p-1)\)

但这样可能还是会递归很多次:考虑有 \(p = (q+1)x + (r-x)\),所以算 \(\log(x-r) - \log(q+1)\) 其实也行的。

那我们只需要 \(\log(r) / \log(x-r)\) 的一个就行,必然有一个 \(\le \frac{x}{2}\),所以递归 \(O(\log x)\) 次就行了。

记录

hdu 11s 的代码,本地只跑了 4s......

13. GG and YY's Binary Number

很好 HDU 题,赛时在函数里 memset 了 int*,改掉就过了...

我们以下认为 \(n,m,\log V\) 同阶。

考虑对 \(L=R\) 的计数,则等价于一个 xor 方程组;如果无解(等价于出现零行的对应系数是 \(1\))则答案为 \(0\),否则答案就是 \(2^{cnt}\),其中 \(cnt\) 为自由元个数。

考虑对 \(\le L\) 的计数,不妨考虑对 \(\lt (L+1)\) 的计数,则我们需要枚举 LCP,然后对前缀做消元。

这样每个询问都带来 \(n\) 个方程,那要做 \(n^2\) 次消元,单组数据的复杂度都达到了 \(\frac{n^5}{\omega}\) 的级别,非常恐怖。

我们仿照线性基的过程,在消元的时候不进行行的 swap,而是把当前行里第一个以前不是主元的位置设为主元;这样每个询问带来的 \(n\) 个方程其实也就是在从上往下一行一行确定当前行的系数,这样的话我们可以直接把 \(O(n^2)\) 个询问同时作为系数列一起消元,最后只做一次;复杂度 \(O(\frac{n^4}{\omega})\)

这样还是太浪费了,因为每个询问的 \(n\) 个方程之间有很大的关联性。考虑这样的一个手法:我们的参数列只有一列(最右边那部分),每个元素都是行的一个线性组合,初始第 \(i\) 行的线性组合只有位置 \(i\)\(1\);在倍加的过程中我们对线性组合也做这样的修改。

这样的话如果矩阵 \(n,m\) 同阶则消元的复杂度是不变的,在这里也就是 \(O(\frac{n^3}{\omega})\)

然后好处是,如果我们此时传入了一组初始的参数 \((v_1,v_2,...,v_n)\),则可以 \(O(n^2)\) 推出消元过后的每一行的参数,然后同样 \(O(n^2)\) 的时间内会代,这个技巧可以直接用进 CF446D,很擅长处理多组方程组,但是方程一样,只是右边参数不一样的情况。

回到这里,我们虽然在 \(O(\frac{n^3}{\omega})\) 的时间内完成了消元部分,但是对于 \(n^2\) 个询问还是要花 \(n^4\) 的时间回代?这里就可以利用到询问的关联性,\(LCP=i+1\) 的询问直接在 \(LCP=i\) 的询问上添加了一个线性组合,而这单个线性组合的计算可以辅助 bitset,所以这部分也做到了 \(O(\frac{n^3}{\omega})\)

记录

14. Randomizer

考虑凸多边形内整点可以用 pick 定理算,那我们要知道:期望面积和边界上的期望整点数目。

期望面积可以拆成相邻两点的叉积和,期望整点当然也可以拆成相邻两点的连边的整点数目和(这个是经典结论,答案就是gcd);所以直接就能导出一个 \(O(n^2)\) 的做法。

这个时候已经优化不了了,怎么办?

不怎么办,一条边出现的概率大概趋近于 \(2^{-d}\),其中 \(d\) 是间隔,当 \(d\) 太大的时候,由于这个概率太低了,对答案的贡献微乎其微,直接不算就行了。大概算到 \(d=60\) 就行了......

我们实数期望是这样的。

记录

15. Alice and the Cactus

首先有 \(E( (x-E(x))^2 ) = E(x^2 + E(x)^2 - 2xE(x) ) = E(x^2) + E(x)^2 - 2E(x)^2 = E(x^2) - E(x)^2\),所有随机变量的方差都能用这个套路。

\(E(x)^2\) 肯定好算,我们算 \(E(x)\) 就行了,利用上仙人掌的性质,答案是 \(a-b+c\),其中 \(a\) 是点数,\(b\) 是边数,\(c\) 是环数。

\(E(a) E(b) E(c)\) 都很好算。

\(E(x^2)\) 就要算 \(a^2,b^2,c^2,ab,ac,bc\) 的情况了,但是讨论一下位置关系都是能算的😅

记录

16. Game Relics

这个题很神啊。

首先注意到 \(x\le c_i\),这个可以告诉我们我们肯定是先抽卡再买卡。

并且容易认识到如果我们此时拥有的物品集合为 \(S\),且这个时候我们从抽卡变成买卡,则对于一个 \(T\in S\),此时一定是抽卡;对于一个 \(S\in T\),此时一定是买卡。(\(T\neq S\)

但是我们什么时候会从抽卡变成买卡??

设我们已经有了 \(a\) 张,则我们可以看作期望花费 \((\frac{a}{n-a}+1) \times \frac{w}{2}\) 的代价从剩下的 \(n-a\) 里随机一张卡获得。

这个值只和 \(a\) 有关,记作 \(f(a)\)

注意到买卡是期望花费 \(sum\) 收益也是 \(sum\),其中 \(sum\) 是剩下的 \(c_i\)。那如果 \(f(a) \times \frac{sum}{a}\) 比这个大我们就会抽卡,否则就买卡。

对于一个局面我们只关注 \(a,sum\),那可以用这个作为状态,但你注意到两个状态 \(sum\) 相同,由于 \(c\) 不同,则转移出去的状态也不同,这是一个无法转移的状态。

而如果我们换个视角算所有状态:从前往后做背包,然后记录 \(a\)\(sum\),这样确实能考虑到所有状态,但是有些状态他是走不到的:我们在他的前置状态就选择了买卡,然后在那里把剩余的买卡的代价全算掉了,那这里就不应该再算一次买卡的贡献。

所以我们考虑把买卡也拆分成多步去做,把它看成期望花费 \(\frac{sum}{n-a}\),然后从 \(n-a\) 张里随机抽一场。那你注意到我们就是在看每一步 \(f(a)\)\(\frac{sum}{n-a}\) 的大小,并且把小的累积到答案。这样就成功把一个过程拆分给了每一步。

时间复杂度 \(O(n^2\sum c)\)

记录

17. Diagonal Fancy

我们规定以 \((1,1)\) 为左上角,称斜线是左上 -> 右下类型的;则一个方阵合法,当且仅当任意斜线上的点全部相同,且没有两条同色斜线。

我们枚举左下角,发现 \((i,j)\) 的答案和 \((i-1,j+1)\) 的答案有单调性:如果 \((i,j)\) 有长度为 \(len\) 的方阵,则 \((i-1,j+1)\) 一定有长度为 \(len-1\) 的方阵,这就可以对于每条反斜线,从右往左地双指针了。

我们只需要处理出 \(f(i,j)\) 表示 \((i,j)\) 和左上角的格子是否同色,以及 \(g(i,j)\) 表示 \((i,j)\) 和右下角的格子是否同色;然后维护 \(f\) 的列区间和,和 \(g\) 的行区间和即可。关于颜色互不相同,只需要用 set 记录当前出现的所有颜色来判;进一步降低复杂度,可以直接用桶,然后记录一下加进过桶的所有数,这样清空的复杂度就有保证了。

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

记录

18. Permanent

很好的题目!

我们先来考虑提取出那些有关键格子的行列,然后一个比较容易的想法是只考虑这些关键行,然后看他们是否在关键列上。然后发现如果我们钦定行的集合恰好为 \(S\) ,满足这些行里选的格子,在关键列上,其实是比较困难的,因为那些不在 \(S\) 的行,它们分别有一些列就不能选了。

所以类似容斥地想法:我们定义一个格子如果值为 \(w\),则它有两种权值 \(w-1\)\(1\),然后可以从二者任选其一,这样可以解决后续的很多问题!

此时我们枚举一个行的集合 \(S\),这些行都要选关键位置,且列不相同。然后剩下 \(n-|S|\) 行,每行的剩余位置都是可以自由选的(且贡献均为 \(1\),就算有特殊格子,因为你钦定只有 \(S\) 的这些行选特殊位置,所以那个 \(w-1\) 就算有也可以忽略),因此贡献就是 \((n-|S|)!\)

换言之我们相当于需要求出所有的 \(f(i)\),表示选出 \(i\) 个行列不交的格子,他们的 \((w-1)\) 的乘积的和。然后 \(\sum f_i \times (n-i)!\) 就是答案。

然后我们其实已经得出了 \(2^k poly(k)\) 的做法了。事实上这一步动机是可以窥见的,因为如果上来套容斥模型,可以得到相同的效果。先前在 ISIJ T2 的时候我从容斥的角度推出了换成 \(w-1\) 这个手法,然后 cxl 好像一眼就说直接换成 \((w-1)\) 了。。。。。。

这样还不够啊啊。

考虑对行列建二分图结构!然后我们发现不同连通块的计算是独立的,得到的 \(f(i)\) 卷起来就好了,这是很有启发性的一个东西。

然后想了很久的折半终于可以套进去了:考虑左右一定有一边点数不超过 \(\frac{k+1}{2}\)(因为最多有 \(k+1\) 个点),对这部分状压。也就是我们不妨设左部点数很少,那就右边一个一个点算,记录 \(f(i,mask)\) 表示考虑到右边第 \(i\) 个点,然后用了 \(mask\) 内的格子。

这样可以做到 \(O(2{\frac{k+1}{2}}\times k^2)\) 了。

但是还是不够,如果两边都有 \(25\) 个点那就寄了。

注意这种情况下这个连通块的非树边很少,然后直接暴力枚举 \(k-siz+1\) 条非树边的使用状况,然后跑 \(k^2\) 的树上背包,然后这部分就解决了。

平衡一下,这个题就在 \(O(2^{\frac{k}{3}}k^2)\) 的时间内解决了!

记录

19. New Year and Boolean Bridges

A 关系的话就是相当于两个人在一个连通块,而且注意到整个图得是弱联通的。所以最后发现我们会把剩下的连通块连成一条链,这样他们之间的 OR XOR 关系全部满足了。

考虑 A 关系形成的若干个连通块:注意到如果两个连通块之间的关系只有 OR 的话:我们可以把若干个连通块再合并到一起。

\(x\) 个点合并成连通块的代价是 \(f(x) = [x\gt 1] \times x\)。也就是成环。

因此如果有 \(a\) 个连通块连成一条链,代价是 \(a-1 + \sum f(x)\)

这个东西等价于 \(n-1 + \sum [x>1]\),所以我们只需要让大于 \(1\) 的连通块数量最少。

所以大小 \(=1\) 的连通块永远保持独立,然后如果两个连通块之间没有 OR 关系我们可以合并!

现在考虑最多 \(m=23\) 个大小 \(\ge 2\) 的连通块,如果两块之间有 XOR 关系就连边,则我们可以把一个独立集合并在一块。

然后问题变成了把一个 \(m\) 点的图分割成最少的独立集个数,也就是图的色数。

虽然是 NPC,但是 \(m=23\) 啊?

考虑用 FWT 维护这个事情,最朴素的想法是我们枚举答案 \(ans\),然后把 FWT 数组的 \(ans\) 次方(点乘)IFWT 回去,这样是 \(m^22^m\) 的。

但是我们只需要求 \(2^m-1\) 这个位置,所以每次可以 \(O(m)\) 算。这样就变成 \(m2^m\) 了。

记录

20. 小火车

这个题也很精妙!

考虑我们随便选两个不同子集,使得和在模 \(p\) 意义下同余,他们相减就是答案,根据 \(2^n\gt p\) 易得一定有解。

然后 \(2^n\) 级别的做法不就出来了,问题变成我们怎么快速找这样的两个集合。

\(n=40\) 就考虑折半,但是直接折半半天也做不了这个东西。

我们可以 \(2^{\frac{n}{2}}\) 地做到这样一个事情:给出 \([L,R]\) 询问多少个集合的和落在 \([l,r]\) 中。

利用这个东西,我们其实可以 \(O(\log p)\) 地定位出一个 \(x\) 使得至少存在两个子集和为 \(x\)

假如我们知道有大于 \(r-l+1\) 个人落在 \([l,r]\) 中,那必定有一个位置被落了两次,初始这个范围是 \([0,p-1]\)

考虑如果 \([l,mid]\) 的个数 \(\gt mid-l+1\),则这里一定有一个位置被落了两次;否则可以推出右半边的个数 \(\gt r-mid\),那右半边有一个位置被落了两次。

这样二分就好了。

时间复杂度 \(O(2^{\frac{n}{2}}\times \log p )\)

最后这一步是神中神。

记录

21. Coffee Varieties (hard version)

考虑这个询问的东西,实质上我们可能是需要做到:对每一对 \((i,j),i\lt j\) 都有一个时刻,满足 \(i\) 在队列里且询问 \(j\) 的。

考虑 \(k\) 的存在,那我们可以分块,按照 \(\frac{k}{2}\) 为长度来分块,这样我们用 \(k\) 次就可以问出两个块之间 \(\frac{k^2}{4}\) 对关系。但这样次数还是非常多。(实际上 \(k=1\) 的时候,可以看成 \(k=2\) 的情况,因为你问两个人 \(i,j\) 还是能做到的。)

注意到一个事情,如果我们有一条链,然后按照这个顺序问每个块,那就能直接问出所有相邻的块,而且不用额外的再浪费一些次数(本来问完两个块就要清空,那如果是 \(1\rightarrow 2\rightarrow 3\) 的顺序,就不需要把 \(2\) 清空后下次再加入)。

所以我们考虑把 \(\frac{2n}{k}\) 个点的完全图划分成若干条链,使得每条边都能被覆盖到。

关于这个东西有一个叫做 zig-zag pattern 的东西在:它给出了 \(N\) 是偶数的情况下,用 \(\frac{N}{2}\) 条链覆盖这张图的方法:我们对于每个 \(i \in [1,\frac{N}{2}]\),从 \(i\) 开始,路径依次经过 \(i-1,i+1,i-2,i+2\),直到路径长度为 \(n\)(这里的下标是在 \([1,n]\) 意义下)。

然后每条链的次数是 \(n\) 次,所以我们就在 \(\frac{n^2}{k}\) 的次数内问出来了所有信息,爆标了。

记录

22. Everywhere is Sparser than Whole (Judge)

神题。

首先考虑 \(\frac{|E|}{|V|} \ge D\) 也就是 \(|E|-D|V| \ge 0\)

也就是我们要选出一个 \(|E|-D|V|\) 最大的导出子图。

\(E\) 固定的时候,\(|V|\) 直接就确定了。所以现在有 \(DN\) 条边,\(N\) 个点,每条边有 \(1\) 的贡献,每个点有 \(-D\) 的贡献,选一条边就必须选两个点。

这是最大权闭合子图模型,然后跑一下最大流,我们注意到它一定不超过 \(DN\),当他 \(\lt DN\) 的时候肯定就是寄了,但是 \(=DN\) 的时候,我们注意题目描述是真子集,所以还不能判断。

很神的一步是:考虑此时每个点都被 \(D\) 条边流到,这 \(D\) 条边定向为从这个点指出,则我们把整张图定向为了有向图,且每个点的出度都为 \(D\)。此时我们缩点完看是不是只有一个 scc 即可。

时间复杂度在于第一部分,令 \(m = \sqrt{DN}\) 则复杂度为 \(O(m\sqrt m)\)

记录

23. 异世界的文章分割者

首先 \(k=1\) 的时候等价于求 \(w(1,n)\),而我们注意到求单串的价值并不是一眼就会一个很好的做法的。另一方面如果我们能 \(O(n)\) 算出一个长度为 \(n\) 的串的权,利用权值单调的性质,可以二分答案后贪心,贪心的过程还需要二分每一段的最长长度,那就可以做到 \(O(n^2 \log^2)\),看上去就能获得 \(60\) 分。

所以首先来思考如何 \(O(n)\) 求一个串的权值,考虑直接把 \(w_{1\sim n-1}\) 算出来,考虑一个串 \(S\) 的 endpos 集合里的最大值和最小值,则要求 \(i\) 位于 \([mn,mx-|S|]\) 之间。对于一个 SAM 上的节点,对应的长度在 \([L,R]\) 中间,经过一些平凡的处理(将 \(R\)\(mx-mn\)\(\min\),然后如果 \(R\lt L\) 就忽略)后,发现对 \(w\) 的修改可以用二阶差分去维护。这样我们就可以 \(O(n)\) 算一个串的答案了。

我们来考虑二分以后贪心的过程,这里可以把二分换成倍增,但这个倍增要这样做:从 \(2^0\) 开始尝试跳,跳到 \(2^k\) 跳不动的话,就从 \(2^{k-1}\) 开始往回检查。这样每个值可以被唯一得到,且设段长为 \(t\),则复杂度是 \(O(t \log)\) 的,所以单次的 check 是 \(O(n\log)\) 的,整个题就是 \(O(n\log^2)\) 了。

记录

24. AmShZ Farm

先来考虑什么样的 \(a\) 序列是合法的,有这样一个描述:按照 \(i\)\(1\rightarrow n\) 的顺序,初始这个人位于 \(a_i\),一旦这个位置已经被占用,就继续向右走,找到第一个没有被占用的位置,然后坐下。则合法等价于每个人都能坐下。

这个模型是一个很经典的 trick:我们虽然无法快速判定,但是可以把他转成一个 \(n+1\) 个点的环,每个人在环上向右走到第一个没被占用的位置,然后合法等价于 \(n+1\) 是没被占用的那个位置(显然最后有且仅有一个位置空下)。

我们把值域拓展到 \([1,n+1]\),首先这样做不会让合法序列变多,其次此时有了对称性,所以环上每个点被留下来的概率相等,所以只考虑 \(a\) 序列的话,就有 \((n+1)^{n-1}\) 种合法方式。

更进一步地根据对称性,对 \((n+1)^{n}\) 个所有可能的序列(不要求合法)算他们的 \(b\) 的数量然后求和,最后除以 \(\frac{1}{n+1}\) 就是答案。因为我们可以把一个序列的数全部 \(+c\)(保持在 \([1,n+1]\) 这个值域范围内),然后每个等价类都有 \(n+1\) 个序列,且恰有一个合法(比如 \(\{1,2,3,1\}\)\(\{2,3,4,2\}\) 就是一个等价类),且他们的 \(b\) 序列的数量都完全相同。

考虑对于一个 \(a\) 序列它的贡献是所有元素的贡献之和(设这个元素出现了 \(a\) 次则贡献为 \(a^k\)),交换求和顺序,枚举一个元素 \(c\),然后枚举它的出现次数 \(a\),然后计算多少个序列里它恰好出现了 \(a\) 次,显然是 \(\dbinom{n}{i} n^{n-i}\)(注意我们把值域拓展到了 \([1,n+1]\),所以去掉 \(c\) 本身还有 \(n\) 个数可以选)。

由于每个元素地位都相等,所以就是 \((n+1)\times \sum_{i=0}^{n}\dbinom{n}{i}n^{n-i} \times i^k\),而因为我们最后还要把答案除以 \((n+1)\),所以要求的就是:\(\sum_{i=0}^{n}\dbinom{n}{i}n^{n-i}\times i^k\)

接下来进入推式子环节,利用大家喜闻乐见的手法:一般幂转下降幂,可以得到:

\[=\sum_{i=0}^{n}\dbinom{n}{i}n^{n-i}\sum_{j=0}^{k}\lbrace ^k_j \rbrace i^{\underline{j}} \\ =\sum_{j=0}^{k}\lbrace ^k_j \rbrace \sum_{i=0}^{n}\dbinom{n}{i}n^{n-i}i^{\underline{j}} \\ =\sum_{j=0}^{k}\lbrace ^k_j \rbrace j! \dbinom{n}{j} \sum_{i=0}^{n}\dbinom{n-j}{i-j}n^{n-i} \\ =\sum_{j=0}^{k}\lbrace ^k_j \rbrace j! \dbinom{j}{j} (1+n)^{n-j} \]

然后第二类斯特林数的一行可以直接 NTT 求出,时间复杂度 \(O(k\log k)\)

记录

25. Sequence

爵士数数好题。

首先注意到我们的序列是严格单增的,所以我们只要确定了选的值构成的集合,就能确定整个序列。

注意到若 \(x\) 选了,则不能选 \(x+n\)。因此我们考虑前 \(n\) 个数如果确定选了 \(p\) 个,则第 \(n+1\sim 2n\) 个数最多还有 \(n-p\) 个可以选。

也就是每 \(2n\) 个数我们只能选 \(n\) 个,而你注意到我们最后是有 \(2tn\) 个数,选 \(tn\) 个,所以 \(n+1\sim 2n\) 要把 \(n-p\) 个都选满,然后 \(2n+1\sim 3n\) 要把 \(p\) 个都选满(和 \(1\sim n\) 一样的选法),依次类推。换言之我们得到结论:只要确定了前 \(n\) 个数的选法,则序列唯一确定,因此答案和 \(t\) 无关。

然后考虑前 \(n\) 个数里怎么样选是合法的:第一个数必选,最后一个数必不被选;然后要求不能有连续 \(d\) 个不选的(对应 \(a_{i+1}-a_{i}\le d\)),也不能有连续 \(d\) 个选的(这样 \(n+1\sim 2n\) 就会寄);其实还有一点:假如最开头有 \(a\) 个选的,结尾有 \(b\) 个选的,则还要满足 \(a+b\lt d\),因为你要考虑 \(1\sim n\) 里最后一个选的和 \(n+1\sim 2n\) 里第一个选的,它们之间间隔不能 \(\ge d\)

不妨把选和不选看成染黑色/白色,然后我们要求每一个颜色段的长度 \(\lt d\),且开头结尾两段加起来之和 \(\lt d\)。由于我们钦定开头黑色,结尾白色,则一定形如:黑白黑白黑白...黑白黑白,我们这样去分组:黑(白黑)(白黑)(白黑)白;也就是结尾和开头成为一组,然后中间的两两分组。对于结尾和开头的组,考虑其生成函数应该是 \(G(x) = \sum_{i=2}^{d-1}(i-1)x^i\),也就是 \([x^a]G(x)\) 对应了这两段长度和为 \(a\) 的方案数;对于中间的这些组,考虑其单个的生成函数应该是 \(F(x)=(\sum_{i=1}^{d-1}x)^2\),这个 \(F(x)\) 容易 \(O(d)\) 求出,然后我们要求的就是 \([x^n]\sum_{i\ge 0} G(x)\times F^i(x)\)(枚举中间组的个数),这个等价于 \([x^n]\frac{G(x)}{1-F(x)}\),套用 bostan-mori 求 \(\frac{P(x)}{Q(x)}\) 的第 \(n\) 项,则复杂度为 \(O(d\log d\log n)\)

记录

26. Capoo on tree

爵士数据结构好题。

对于静态的问题,考虑按照 \(y\) 扫描线,树剖后变成区间问题,然后我们就要依次点亮某个位置,可以用线段树二分来解决。

这个修改看起来非常难以处理,如果用常规的根号分治等思想不可行,考虑先把静态的问题在线,用主席树维护。然后我们修改的时候去更新主席树,当令区间 \(x\leftarrow x-1\) 的时候,实际上是让时刻 \(x\) 的主席树变成了时刻 \(x+1\) 的主席树(反之,就是让时刻 \(x+1\) 的主席树变成时刻 \(x\) 的主席树)。我们在线段树上递归的时候,进行节点的复制即可。

时空复杂度均为 \(O(n\log^2 n)\),这里写起来有不少细节问题需要处理:首先我们为了确保线段树二分的复杂度正确,需要维护区间内的最长段长度,前缀长度,后缀长度;还需要注意到我们要考虑树剖出来的不同段之间的相互影响:当我们查询 dfs 区间 \([l,r]\) 内的点的时候,需要忽略 \([r+1,n]\) 内的激活的点,但是不能忽略这条路径之后的那些点。例如如果我们剖分出 \([1,3] [7,9]\) 两个区间,则我们在 \([1,3]\) 这里线段树二分的时候,需要知道 \([7,9]\) 这个部分的前缀信息。

记录

27. Assignment

爵士动态规划好题。

\(f(l,r,i)\) 是仅考虑 \([l,r]\) 区间,允许最多 \(i\) 个位置不同的答案。

如果有一个位置没有被操作覆盖到,则我们可以枚举这个位置 \(p\),然后把 \(f(l,p-1)\)\(f(p+1,r)\) 卷起来。

否则每个位置都被做了至少一次操作,此时 \(a_i\) 是什么已经不重要了。我们设 \(g(l,r,i)\) 是此时的答案。

有结论:除非我们选中了一个操作覆盖 \([l,r]\),否则必定存在一个断点 \(p\),使得没有操作跨越 \(p\)

这个证明很容易,然后对于存在断点的情况,也很容易。问题是我们选中操作覆盖 \([l,r]\) 的情况。

它成立当且仅当 \(b_l=b_r\),然后我们第一次把整个区间都染色成 \(c=b_l=b_r\),然后我们选择若干个区间,它们还会进一步染别的颜色,剩下的部分就确定是颜色 \(c\) 了。

这部分的转移是一个类似背包的过程,每次直接做肯定是死亡的。但是我们可以把这个东西也单独开状态:\(h_{l,r,i}\) 表示考虑区间 \([l,r]\) 染颜色 \(b_l\),不超过 \(i\) 个位置不同的情况。这样当我们确定了 \([l,r]\) 的信息,对所有的 \(h[x,l-1]\) 进行 \(h[x,l-1] + h[l,r] \rightarrow h[x,r]\) 的卷积就行。

注意这个背包设计出来后需要注意一下转移的顺序。时间复杂度 \(O(n^3k^2)\)

记录

28. Make 2

牛魔题。

首先可以观察出没有 \(a_i\gt 3\) 的,事实上如果有 \(3\) 一定是 \(131\) 的形态然后一步变成 \(222\),所以如果有这种东西我们就直接删掉,然后考虑 \(a_i\le 2\)

手玩一下发现 \(1221\) 是有救的,\(12121\) 也是有救的,好像 \(1221\) 的中心塞若干个 \(1\) 都是有救的。

然后塞任意个 \(2\) 也可以,这样写了一下过不去 \(m=0\) 的第三个样例,然后紫砂了。

最后才发现还有 \(11211\) 这个神必存在,加上去就可以过 \(m=0\),然后 \(n\) 更大的情况可以直接套矩阵快速幂,但写起来已经很麻烦了。

考虑这种结尾加串的题可以套 DFA:可以构建出一个六个点的 DFA 满足所有转移,这样 \(m=0\) 就很好写了,然后 \(m\gt 0\) 的话也就是钦定某一步我们必须走标号为 \(1/2/3\) 的出边,那只用做 \(O(m)\) 次矩阵乘法就好了,时间复杂度 \(O(m\log n)\)

记录

29. Boring Lectures

考虑所求即距离不超过 \(k\) 的点对的最大值。按照长度为 \(k\) 分块,则两个点所位于的块要么相同,要么相邻。

相同很好处理,但是相邻的情况比较麻烦。可以发现:二者必定有其一是块内最大值,发现后不难证明。

假设两个块的最大值分别为 \(a,b\)(我们假设 \(a\le b\)),那么设分别取了 \(c,d\),则必须有 \(d\gt a\)\(c\gt b\) 成立。但是注意到我们已经假设 \(a\le b\)了,所以 \(c\le a\le b\) 啊啊,这就矛盾了。

然后我们就可以用线段树维护了,时间复杂度 \(O((n+q)\log)\)

记录

30. Border Queries

首先研究什么时候 \(t\) 是好的,也就是 \(s_1ts_2 = s\)\(s_1\)\(s_1t\) 的 border 且 \(s_2\)\(ts_2\) 的 border。

画一下可以发现:等价于 \(s_1+s_2\)\(s\) 的 border。

稍微示意一下:

AAAAABBCCCC
..AAAAACCCC
AAAAACCCC..

这三个串显然都是相同的,然后下面两个串其实就揭示了 \(s_1 + s_2\)\(s\) 的 border。

注意到 \(s_1,s_2\) 非空,所以 \(t\)\(s\) 去掉开头结尾后的子串(记作 \(s'\)),且 \(|s|-|t|\)\(s\) 的 border。

考虑求出集合 \(A = \{n-border\}\),然后我们的询问相当于是问有多少个 \(T[l,r]\) 的子串,满足它的长度在集合中,且它是 \(s'\) 的子串。

考虑对 \(s\) 建立 SAM,然后套用求两串 LCS 的方法,对每个 \(i\),求 \(LCS(T[1...i],S)\),记作 \(f_i\)

然后设 \(g_i\)\(\le i\) 里的 \(A\) 的元素个数,则要求的就是 \(\sum_{i=L}^{R}g_{\min\{j-L+1,f_j\}}\)

注意到 \(j-f_j+1\) 是单调的,而比较 \(j-L+1\)\(f_j\) 就是在比较 \(j-f_j+1\)\(L\),所以可以二分出一个 \(p\)\(i\in [p,R]\)\(\min\) 取右边,此时可以直接前缀和预处理出来;当 \(i\in [L,p)\) 的时候取左边,这个时候时求 \(g\) 的二阶前缀和,也可以预处理出来。

因此在建立 SAM 后,整个问题可以在 \(O(n+m+q\log n)\) 的时间内解决。

记录

31. Teyberrs

牛魔题。

注意到每一列能走到的点奇偶性是确定的,不妨假设 \(s\) 是偶数,然后对于偶数列,我们依次给 \(0,2,4,8\) 标号,对于奇数列,我们依次给 \(1,3,5,7\) 标号。

然后对于偶数列,假设我们位于标号为 \(x\) 的地方,可以花费 \(a\) 的代价走到标号为 \(x-1\) 的下一列,也可以花费 \(b\) 的代价走到标号为 \(x\) 的下一列;对于奇数列,我们可以花费 \(a\) 的代价走到标号为 \(x\) 的下一列,也可以花费 \(b\) 的代价走到标号为 \(x+1\) 的下一列。其实没有区别,因为后一种情况我们,我们按照前者转移,把 dp 值平移一位就好了。所以我们假设都是前面的那样的转移。

可以发现设 \(f_i(x)\) 是走到 \((i,x)\) 的最小花费,则它是下凸的(我们只维护定义域内的,也就是不考虑两边走不到的点)。

因此我们一定是截取一段前缀,这部分做代价为 \(a\) 的转移,然后剩下的部分直接做代价为 \(b\) 的转移。

这个前缀可以二分斜率二分出来,不妨直接用平衡树维护斜率(也就是相邻 \(dp\) 值的差分)。

转移的时候就是在最前面插入一个点,在中间插入 \(b-a\),删除前缀原先的最前的点(因为 \(x\) 最小的那里会新产生一个 \(dp\) 值),合并起来就行。然后在调整到 \([l,r]\) 范围内。

时间复杂度 \(O((n+q)\log)\)

记录

32. Make Biconnected

注意到每个叶子至少得有一条连边,因此答案的下界是叶子的 \(w\) 之和。我们猜测一定能取到。

当叶子数量 \(k\) 是偶数的时候,注意到本题是二叉树,我们以任意一个非叶节点定根,有一个比较经典的结论是我们可以把这 \(k\) 个叶子匹配起来,使得整张图成为一个点双:我们把叶子按照 dfs 序排列,然后第 \(i\) 个叶子和第 \(i+\frac{k}{2}\) 个叶子匹配。

这个情况应该只在二叉树成立,证明可以考虑反证:我们枚举一个点 \(u\),然后看他分裂出的 \(d\le 3\) 个连通块,注意如果我们把下标 \(1\sim k\) 看成一个环,则 \(d\) 个连通块对应的叶子 dfs 序应该形成三个区间。

对于 \(d=2\) 的情况,显然两个区间之间会有连边;对于 \(d=3\) 的情况,要么前两个区间之和 \(\le \frac{k}{2}\),这样他们都和第三个区间又连边,否如果第一个区间 \(\ge \frac{k}{2}\) 了,他和第二个第三个区间都会有连边;不然就说明第一个区间 \(\lt \frac{k}{2}\) 但是第一个 + 第二个区间 \(\gt \frac{k}{2}\),那第一个区间会和第二个区间有连边,第二个区间会和第三个区间有连边。总而言之这棵树的 \(d\) 个部分还是连通的。

而对于 \(k\) 是奇数的情况,显然 \(\sum_{u\in leaf}w_u\) 不是答案,我们至少还要多连一条边。

考虑全局最小的 \(w_x\),则此时下界是 \(\sum_{u\in leaf} w_u + w_x\),这个时候我们再猜测它是一定能取到的。

也就是我们让点 \(x\) 和一个叶子连,然后剩下的 \(k-1\) 个叶子再两两匹配。

什么时候能做到呢?考虑以 \(x\) 定根,然后叶子 \(u\) 不断向上跳,如果路径上全是 \(deg\le 2\) 的点,那我们只连 \((u,x)\) 这条边,然后 \(u\) 不和其它人连边,当我们断的是 \((u,x)\) 之间的一个二度点的时候,\(u\) 就不连通了;反之,找到第一个 \(deg=3\) 的点 \(y\),则 \((u,y)\) 这部分,不管你删哪个点,\(u\) 还是和别人连通的。

所以发现只有一种情况是取不到这个下界的:\(x\) 为根挂了若干条链,在本题里也就是恰好三条。(否则只有两个叶子)。

但这个时候考虑全局次小的 \(w_y\),容易发现是存在 \(\sum_{u\in leaf}w_u + w_y\) 的方式的,所以这题就结束了。

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

代码

33. Count Sorted Arrays

爵士好题。

首先考虑如果我们只问一次怎么办?也就是把 \(m\) 个操作都给你。好像直觉上这个其实和原问题也差不多。

考虑 \(n\) 个数很困难,先来研究 \(1\) 的变化:那初始位置只有 \(n\) 种可能,对于每种可能,我们都能 \(O(m)\) 算出它是否最后会合法。(也就是被换到 \(1\))。

然后考虑加入 \(2\),这个时候就比较麻烦了,因为 \(1,2\) 之间好像还会相互干涉。但假如我们知道 \(1\) 的位置在 \(u\) 且最后会合法,然后 \(2\) 的位置在 \(v\),我们其实只需要保证 \(\{u,v\}\) 这个集合的两个元素在 \(m\) 次操作后都被换到最前面就行了,因为我们知道 \(u\) 会被换到第一个位置,所以 \(v\) 就一定会在第二个位置。

换言之我们维护 \(n\)\(0/1\) 序列:第 \(i\) 个表示 \(\le i\) 的位置集合,只要这个位置集合在 \(m\) 次操作后,能都换到最前面,那就是合法的。

然后一个合法的排列等价于把合法的 \(n\) 个集合串起来,要求第 \(i\) 个集合的大小为 \(i\) 且依次是包含关系。

如果我们知道每个集合的合法性,那就有一个很简单的 \(2^n\times n\) 的 dp 统计答案了。

然后我们可以对每个集合暴力检验,在 \(O(2^n\times m\times poly(n))\) 的时间内求出每个集合的合法性。

现在考虑动态加入一个 \((u,v)\),就修改一些集合的合法性:从不合法变为合法。如果能做到,则考虑一个集合 \(S\) 从不合法变为合法,对 dp 值的影响只发生在 \(S\) 所有超集 \(T\) 的位置。这样暴力修改的复杂度就是均摊 \(O(3^n\times n)\) 的。

于是问题变成怎么快速维护每个集合的合法性。

首先考虑维护进行了当前的所有操作后,每个人会变成谁,假设当前 \(S\) 会变成 \(T\),就在 \(T\) 对应的 vector 里插入 \(S\)

当前加入 \((u,v)\) 的时候,考虑所有 \(mask\)\((u,v)\) 操作对这个集合有效),然后设 \(mask\) 交换后变成 \(mask'\),那也就是把 \(mask\) 的 vector 里的所有集合插入到 \(mask'\) 然后清空(代表着这些人此时会变成 \(mask'\)),并且如果 \(mask'\) 是一个最终合法的状态(也就是元素都在最开头),则它 vector 里的所有元素也会变成合法的状态,此时修改它超集 的 dp。

如果我们能把那些 vector 为空的 \(mask\) 快速排除,可以看到我们均摊一下,修改只有 \(2^n\times n^2\) 次(每个 mask 最多换 \(O(n^2)\) 次就会变成一个最终合法的状态)。

对每个 \((u,v)\) 都维护一个队列,然后发生上面的操作时,把 \(mask'\) 压入所有对应 \((u,v)\) 的队列里(表示它后续还是有机会检查的),没有被压入队列的 vector 肯定此时是空的,然后这个压入次数就是修改次数再乘上 \(n^2\),也就是 \(2^n\times n^4\),但是常数非常小,因此可以通过。

总时间复杂度即为 \(O(3^n\times n + 2^n\times n^4)\)

记录

34. Deque Minimization

好题。

首先考虑单个数的 \(f(X)\) 怎么计算:先加入第一个数,然后依次后面 \(n-1\) 个数的放法。

不难发现如果它 \(\le\) 开头的字符就会放到开头,否则会放到结尾。

可以发现根据这个过程,从一直到第一个数的位置,这部分一定是递增的。

找出 \(Y\) 的极长升序前缀 \([1,p]\),然后枚举第一个数的位置 \(x\le p\),然后按顺序从前往后排出第 \(1\sim x\) 个位置,这些位置称为关键元,问题变成有 \(x\) 个空(第 \(i\) 个空位于第 \(i\) 个位置前),我们要把后面 \(n-x\) 个数按顺序(从 \(n\)\(p+1\) 的顺序,也就是一个数不能在上一个数的后面)插入这 \(n\) 个空中,如果一个数为 \(a\),则插入它时,要求后面至少有一个 \(\lt a\) 的关键元(否则此时我们会把这个元素放在开头)。

因此注意到我们可以把一个 \(\gt x\) 的位置 \(q\) 替换成它在 \((x,q]\) 中的最小值,这样 \((x,n]\) 这段后缀就只有 \(9\) 个递减的段落,然后我们可以设 \(dp(i,j)\) 是考虑完了从后往前的前 \(i\) 个段落,当前插入到 \(j\) 的答案。这样可以得到一个 \(O(n^2)\) 单次的 dp,那还不如直接 \(dp(L,R)\) 表示两边分别归并到了 \(L\sim R\),怎么成 \(n^3\) 了??

考虑对于 \(a_x\) 相同的那些位置,它们对答案的贡献是极其相似:考虑把每段相同的 \([L,R]\) 提取出来,然后计算所有的 \(dp(L,i)\)(记作 \(f\) 数组),然后再用 \(f\) 数组和 \([L,R]\) 的每个位置结合算对答案的贡献;然后转移到 \(dp(R+1)\),这样的好处是我们只关注 \(9\) 个时刻的 dp 值,那么就可以考虑把 \([L,R]\) 这段的转移一口气跨过,这也是很有前途的,因为它们的 \(a\) 都是相同的。

先考虑知道 \(dp\) 算答案:对于 \(x\in [L,R)\),这部分由于第 \(x+1\) 个位置和第 \(x\) 个位置相等,所以它们必须在 \(L\) 之前就全部删除,那就是只用到 \(f(x+1)\),对于 \(x=R\),枚举 \(f(i)\),满足 \((R,i]\) 这部分全部大于 \(a_x\),然后令 \(len=R-L+1\),则答案贡献系数为 \(\dbinom{i-R + len-1}{len-1}\)

然后考虑算 dp:令 \(dp(R+1)\)\(g\) 数组,考虑 \(f(i)\)\(g(j)\) 的转移(其中 \(j\le i\)):这首先要求 \((j,i]\) 的每个数都 \(\gt a\),然后贡献即为把 \(i-j\) 个数丢进 \(len = R-L+1\) 个空的方案数,也就是 \(\dbinom{i-j+len-1}{len-1}\),是一个差卷积的形式。

为了解决 \((j,i]\) 的每个数都 \(\gt a\),注意到其实这等价于 \((p,i]\) 的每个数都 \(\gt a\),随着 \([L,R]\) 的增长,\(i\) 的上界会越来越小,因此我们将那些界外的 \(f\) 设为 \(0\) 即可。

时间复杂度 \(O(\Sigma n\log n)\),本题里 \(\Sigma = 9\)

记录

posted on 2023-08-02 13:49  Cry_For_theMoon  阅读(169)  评论(0编辑  收藏  举报