oi题选做

麻麻麻

Posted by ShanLunjiaJian's Blog on September 13, 2022

从这一篇开始我要使用两个$作为latex的标识符。

polish oi

poi大概是,有三轮,r1五题,r2 r3都是有D0 D1 D2,D0一题,D1 D2两题。

VIII(2000~2001)

Stage 1

A. Liczby antypierwsze

tooooooooooooooo classic。

B. Mapa gęstości

前缀和。

C. Przedziały

模拟。

D. Gra w zielone

幸运的,这个题在谷上有。

请注意是在环上的部分要走过一个绿点,而不是整个/jy

发现如果一个A的点的后继有让A赢的,它就也是赢的,否则它是输的。如果一个B的点后继全是让A赢的,那么它也是赢的,否则它是输的。但是只知道这些不管用,我们可以让所有点都赢,也可以让所有点都不赢。

考虑如果不在环上的绿点也算数的话,那么我们只要一开始让所有绿点赢,然后按上面递推就好了。注意到如果从一个绿点出发必然可以到达自己,那么它必然是赢的,否则这个绿点是无用的。发现我们从有用的绿点出发递推就可以得到正确答案,所以问题是求出哪些绿点是有用的。

做法是,我们先把所有绿点置为有用的,然后有用的绿点必然是赢的,递推出哪些点是赢的,如果一个有用的绿点其实是输的,那么就把它置为无用的。于是每轮减少至少一个绿点,复杂度$O(cm)$。

为了证明这个奇怪东西的正确性,考虑最后每个输的点显然真的不能赢,而每个赢的点确实可以走到一个环上,而由于是从一些绿点开始递推,环上确实必然有一个绿点。

Stage 2

D0

Gorszy Goldbach

找到一些大素数快速减少数的大小。打表即可。

D1

Spokojna komisja

2-sat。

Wyspa

没太看懂题意。应该模拟就行了吧/oh

D2

Mrówki i biedronka

没太看懂题意。应该模拟就行了吧/oh

Podróż

题意不是很懂,看起来是什么大力建图dij?

Stage 3

D0

Wędrowni treserzy pcheł

判定基环树森林同构,考虑基环树,每个子树树hash之后相当于判定两个序列是否循环同构,跑个最小表示然后hash即可。

D1

Porównywanie naszyjników

考虑那个简单的最小表示都需要啥。发现我们需要求lcp,然后需要保证可能作为最小表示开头的位置数量很少。注意到一段只有第一次循环和最后一次循环中的位置可能成为最小表示的开头,所以后者已经结束了,而前者,考虑倍增hash,结束了。

Zwiedzanie miasta

智障了。随便跑一个欧拉回路,然后找到前缀和最小的点,从它出发就得到一个全正的。和raney引理有点像。

D2

Bank

如果只有一种货币,注意到每个人都不会让你的资金量变小,所以我们会每次选择加最少初始资金就能选的。

但是现在有四种货币,感觉上贪心好像真的可以得到一个极优解,我们只需要先让第一种最小,如果有很多个可以选的,让第二种最小,这样的。

Kopalnia złota

枚举一个横坐标,线段树维护纵坐标,那么一个点在一个横坐标区间贡献一个纵坐标区间。

Łańcuch

直接dp。考虑我们首先要让$n-1$是1,剩下的都是0,所以设$dp(i)$表示变成$i$是1前面都是0的步数,为了这么做发现我们只有送一个1上去才能把最低的1拿掉,所以看起来策略就是每次把当前末尾极长我们想要的段(一些0之后一个1)往上扩展一个1,然后把下面那个1扔了,直到够到$n$这样的。

IX(2001~2002)

Stage 1

Superskoczek

我们尝试让马分别往上走一步,往下走一步,往左走一步,往右走一步。注意到必然存在一种方案使得马的坐标绝对值保持在$101$以内。搜即可。

或者使用格的线性基,称为hermite标准化的算法。它收录于 线性代数。我们说说前面怎么做。

首先我们必须可以找到或者组合出四个在坐标轴上的向量,把它们称为简单向量。具体做法就是有就直接取,没有就找最多两个组合。

这个东西是正整数线性组合,那么我们考虑怎么改成整数。现在有一个向量$(a,b)$,我们要凑$(-a,-b)$,不妨设$a,b>0$,想一想发现通过使用$(a,b)$和下半轴和左半轴的简单向量总可以凑出$(-a,-b)$。

然后跑hermite标准型。这个标准型应该包含且仅包含$(1,0),(0,1)$。

Komiwojażer Bajtazar

模拟。

Wyspa

转一圈双指针即可。

Zamek

直接dp。

Koleje

noip2012 借教室。noip出poi原题/jy

线段树模拟一下。

Stage 2

Izolator

这是一个匹配问题。考虑每个数可能贡献正的它,负的它或者不贡献,不贡献显然没劲,然后我们希望让最大的若干个数贡献正的,最小的贡献负的,所以构造一下发现可以最大的$\lfloor\frac{n}{2}\rfloor$个数贡献正的,最小的$\lfloor\frac{n}{2}\rfloor$个数贡献负的。

Działka

模板 最大子矩形。

Wyliczanka

excrt。

Kurort narciarski

还是直接dp。

Protokoły

不是很能看懂题意。不过肯定可以直接dp吧。

Stage 3

Minusy

这个问题好像很经典,似乎在arc出现过。对于每一段连续的加号,我们在两边放一对括号。arc搬poi/jy

Narciarze

这个看起来不是最小路径覆盖啊,也不是最小割。但是上下界最小流就好了!

Waga

背包。

Liczby B-gładkie

数论题/jy

min_25/洲阁筛的第二部分。

Nawiasy

直接dp。

Szyfr

模板 knapsack。折半。

X(2002~2003)

Stage 1

Ciągi bez zająknięć

考虑有没有一个$\log$个的构造。发现可以把原序列复制一份,在中间加入一个没有出现过的字符。

交一发wa了。考虑有没有一个$O(1)$的构造。发现两个字母肯定不行,但是搜一搜或者手动构造,发现三个字母可以构造出$n=8$,一个做法是$abcbabca$。结论是thue-morse序列的差分是square free的。

或者可以大力随。注意到长度超过某个足够大的$k$的square几乎不可能出现,而它们有$n^2$个,那么取$k=120$看起来足够,如果往后加入一个字符后,出现了长度$\leq k$的square,则删掉它。我们只需要维护$k$个前缀和即可。为了证明这个东西的复杂度,请见 https://www.sciencedirect.com/science/article/pii/S0304397515006489。

为了写checker,看起来需要使用lyndon array那一套。

Liczby Przesmyków

数位dp。

Czekolada

也就是如果选一个x的时候,前面有$k$个y被选了,那么它带一个$k+1$的系数。dp即可。

Przemytnicy

dij。

Płytki drukowane

大力dp,直接存两端的状态。

Stage 2

Mastermind II

模拟。

Autostrady

2-sat。hnoi搬poi/jy

Trójmian

读错了三遍题。

弱于 zjoi2017 多项式。

Kafelki

根据周期引理,如果$k+l-\gcd(k,l)\leq n$,那么$\gcd(k,l)$也是周期,并且显然不需要存在比它更小的周期,所以答案是$\gcd(k,l)$。如果$k+l-\gcd(k,l)>n$,那么$\max(k,l)>\frac{n}{2}$,不妨设$k>l$,那么我们知道如果没有$k$,$l$导致了$l$个等价类,而$k$的作用是合并了其中$n-k$对,所以答案是$l-(n-k)$。

Połączenia

考虑k短路说了啥,我们跑一个floyd,从每个点出发建最短路树,然后真的跑k短路。这里我们可以$O(nk)$跑一次,方法是不合并堆而直接爆力向上找。

Stage 3

Gra w dzielniki

如果这个数是一个素数,那么我们就需要遍历所有的素数。所以按任意顺序问所有的素数,问中了就除一下再问剩下的就好了。

Skarb

主要问题是两个人能不能相遇。我们分别找到环,进入环之前模拟一下,进入环之后只需要算个$\gcd$。

Sumy

考虑同余最短路,我们从$0$出发bfs,但是直接做是$O(na)$的,所以bitset维护一下就$O(\frac{a^2}{w})$了。

Kryształ

完全没懂它在说啥。

Małpki

终于有2e5题了。直接拓扑排序。

Tasowanie

把环求出来,然后直接算这个置换就好了。

XI(2003~2004)

Stage 1

PIN-kod

没看懂。

Zawody

模板 有向图最小环。跑两个bfs。

然后发现可能不太对啊!不过我们枚举第一条边走的是哪条边就好了。

Gra

跳棋/jy

读错题/jy

很容易想起sdoi2019 金币游戏,所以我们尝试转成staircase nim。发现两个空格之间就是一个staircase,然后就结束了。

Szpiedzy

也就是有一个内向基环树森林,那么我们在环上枚举任意一个点选还是不选把环断开,在树上直接dp即可。

Sznurki

原来string真的是弦而不是串串。

数量可以直接dp,把子树传上来的接起来即可。长度的话当然二分,然后就是接的时候最长的接最短的,次长的接次短的,这样的。长剖之后计排,复杂度$O(n\log n)$。

Stage 2

Most

好像很经典,但是我好像没见过。

考虑样例,容易想到我们可能让两个很慢的老哥一起过,此时对面需要有一个快的老哥等着回来。也就是说,我们可以

  • 让最快的人带一个人过去

  • 让最快的人和第二快的人过去,最快的人回来,两个人过去,第二快的人回来

一定是一个后缀被第二种带过去,枚举即可。

Bramki

问题是可能有环,有趣的是如果有环的话输出可能仍然是确定的,这个题意大概是对于一开始的状态,按任意顺序调整,直到。类似 viii poi Gra w zielone 的做法,我们全赋成$1$调整一遍,全赋成$0$调整一遍,如果一个门两遍得到的相同,那么它是确定的,否则它是不确定的。

Jaskinia

也就是求一个深度最小的点分治。

看起来很困难。考虑点分治本质是什么,发现它是给每个点分配了一个深度,然后我们找到深度最小的点划分下去,如果这个点唯一那么就可以建立一个分治结构,而唯一当且仅当两个深度相同的点不会出现在同一个分治块,也就是它们之间的路径上有一个深度更小的点已经把它们分开了。

考虑自底向上做,维护哪些深度有一个点满足上面还没有一个深度更小的点,这里深度是$\log$级别的。然后合并子树的时候如果有相同的,那么这个点的深度必须比它们小,分配尽可能大的深度即可。这么做是不劣的,因为大的深度可以由大的深度来解决,小的深度则需要小的深度,这玩意感觉上有点类似树上的某种进位,但是不是很理解啊。

考虑用一个简单的东西描述一个过程,这种做法可能叫compress?感觉它可以帮助你换扫描线方向,比如点分的方向是在点分树上扫,但是我们描述了点分树之后,就可以直接在原树上扫。但是也许除了点分治以外没有哪个题可以这么做了。

Przeprawa

又见面了。然而好像没有,这个直接爆力即可。

Turniej

考虑一个波特什么时候能赢,我们认为一条边从赢指向输,那么如果把没有边都当成双向边,从它出发可以到达每个波特,它就赢了,构造方法是在生成树上自底向上进行比赛。但是这个好像不是很行。

注意到如果有超过一个波特能赢,那么一个波特能赢,当且仅当它可以打败一个能赢的波特,因为它必须打败所有波特,而打败了一个能赢的波特的话,只需要先让这个波特打败别的所有波特即可。所以我们找到一个能赢的波特,然后找到所有可以打败它的波特,就得到了答案。

考虑凑一些限制,如果波特$u$必然不能打败$v$,那么说明$v$必然打败$u$和所有$u$可能可以打败的波特,那么$v$的出度必然严格比$u$大,所以我们知道出度最大的波特必然可能赢任何波特。

接下来找到所有能赢的波特,我们知道如果不是所有能赢的波特都到某个波特有边,那么这个波特也能赢。一开始把出度最大的波特标记为能赢的,每次取出一个能赢的波特,维护一个还没能赢的波特的列表,找到所有它不必然打败的波特,标记为能赢的。注意到每次一个还没能赢的波特没有被标记为能赢的,都要求新处理的能赢的波特到它有边,所以复杂度是线性。

Stage 3

Zgadywanka

为了得到满分,你需要赢三场。

我们直接找到概率最大的。如果这个数是$x$,还有$t$个数没出现,其中有$k$个$<x$的概率就是$x^k(1-x)^{t-k}$。

Wschód-Zachód

注意到主要问题是要到达中间那个狭窄的地方。直接在东侧模拟即可。

Wyspy

怎么还计算几何的。

为了把树建出来,经典做法是从边上往外画一条射线,考虑撞到的第一个多边形,它要么是父亲要么是兄弟。为了避免成环,每个多边形从最右的点往右画射线即可。为了画这个射线,使用线段树维护。

Kaglony

对于第一种,我们可以把每个连通块分开。对于第二种,在补图上把每个连通块分开。

但是怎么算补图的连通块啊?简单想法是bitset,复杂想法是别乳卡。更简单的想法是,我们每次加入一个点,然后枚举它的邻边,如果一个连通块中不是每个点都和它有邻边,那么发生了一次合并,这个可以维护没有边的连通块的列表做到线性。注意到每两轮必然分别是两种情况,所以边数会减少至少$n$,并且进行$n$轮必然结束,所以轮数是$O(\min(n,\frac{m}{n}))$的,当然一般来说很松。复杂度$O(m\sqrt{m})$。

Maksymalne rzędy permutacji

周期是所有环的周期的$\operatorname{lcm}$。为了最大化这个,我们必然选择一些不同素数的幂,然后从小到大排列它们,对得到的每一个区间转一下。现在问题是最大化$\operatorname{lcm}$,dp值我们猜测取个$\ln$就赢麻了,所以要用若干个素数幂做背包。为了卡常,注意到很大的素数不会用到,扔了就赢了。

Misie-Patysie

相当于平面上有一个棋子,你可以往左,往下,往左下移动。

不知道干什么的时候你就打个表,发现先手必败的状态$0$很少,只看$x\geq y$的部分,那么可以这么走出来 : 每一步可能是$x+=2,y+=1$或者$x+=3,y+=2$,记前者为$1$后者为$2$,则$0$的位置可以通过一个序列生成,序列的构造方式是一开始有一个$1$,接下来每次把$1$替换成$12122$,$2$替换成$12122122$。我们需要每次移动到一个$0$上,那么生成所有的$0$,然后找到一个即可。直接生成会得到长2e7的串,其实挺可以接受,但是你也可以预处理每一轮保留多长做到恰好够用。

XII(2004~2005)

Stage 1

Bankomat

一个密码可能出现,当且仅当去掉相邻的重复元素之后,它是所有移动序列的子序列。对每个串建子序列自动机,然后枚举每个密码上去跑,复杂度$O(10^lnl+\sum \vert t\vert)$,其中$l$当然是密码长度。

Punkty

经典问题是判断两个多边形是否相似,做法是转一圈求相邻边的点积和叉积,然后跑一个最小表示判断是否相等,如果允许对称则翻转之后再跑一遍。

现在问题是我们没法唯一地连成一个多边形。考虑求出凸包,剥掉凸包,求出凸包,剥掉凸包,如此直到所有点都被剥掉,然后依次比较每个凸包,每个凸包会确定一圈可能的变换,然后我们需要对这些东西求一个交,看起来很复杂啊。

考虑有没有一个简单想法。我们首先确定平移量,发现找到重心,然后把重心平移到重合即可。然后考虑放缩,可以选择距离重心最远的点,把这两个距离放缩到相等。然后考虑旋转,我们从重心出发记录相邻两个点的点积和叉积,然后跑最小表示。

Samochodziki

这个是 模板 离线寄存器调度问题。做法是贪心把下一次选择时间最远的放回去。

Skarbonki

当然是内向基环树,我们打开环就赢了,为此需要打碎每个环上一个点。

Skoczki

又见面了/jy

Stage 2

Lot na Marsa

又见面了/jy

然而这个没那么原,因为它让你求出所有解啊。问题是查询区间最小前缀和,这里单调队列即可。

Banknoty

已经不会背包了。单调队列。

Sumy Fibonacciego

加起来爆力模拟进位。

Kości

也就是给图定向,使得出度的最大值最小。二分答案,然后考虑网络流,直接建就行了,复杂度$O(m\sqrt{m}\log n)$。

Szablon

好像前两天汪娟给我看这个题来着。考虑答案必然是一个前缀,当然也必然是一个后缀。我们枚举一个前缀,考虑所有它的出现位置,如果这些出现覆盖了整个串那么就可行,这可以z algo求出来。所以我们只关心相隔最远的两次出现。从短到长枚举前缀,那么出现的集合会逐渐缩小,用链表维护所有的出现即可。

Stage 3

Dziuple

也就是求二分图的平面嵌入数。考虑连通怎么做,注意到如果左部最下面那个点是$u$,那么$u$的邻接点只能有最多一个还有别的出边,否则就会相交。设这一个点是$v$,那么$v$的邻接点只能有最多一个还有别的出边。所以图必然是一个毛毛虫,我们把主链两端的叶子数$+1$再乘起来,剩下的叶子可以随便排列,还要考虑翻转链和放在哪一边,再乘一个$4$得到答案。注意单点需要特殊处理。

考虑不连通怎么做,不是单点的连通块之间排一排,单点则可以插在任意位置。

Akcja komandosów

没太看懂。据说是求最小的前缀使得这些圆没有交。

考虑了随机增量,好像不太行。

考虑我们找到交中最右的点和最左的点,考虑前者,发现这个点必然是由一个圆中最右的点或者两个圆的交中最右的点贡献,继续发现它必然是所有两个圆交中最右的点中最左的。所以爆力枚举即可,复杂度$O(n^2)$。

Dwa przyjęcia

猜测答案必然是$n$。归纳,如果所有点都是偶度点就赢了,否则删掉一个奇度点$u$,得到一个方案,那么$u$必然到其中一边有偶数条边,另一边是奇数。不管加入到哪一边,$u$加进去之后,邻接点的度数就都变成奇数了,于是我们考虑能不能通过加一些边再递归下去,然后把这些边删掉换成$u$和它们之间的边。把邻接点之间的边全部取反然后递归,此时删掉这些边,那么到$u$有偶数条边的部分,$u$的邻接点度数都是奇数,此时加入$u$就赢了。

译自 Combinatorial Problems and Exercises by László Lovász。

Dwuszereg

容易想到抽象成xor方程组,这里问题是什么有若干个$x_i\operatorname{xor}x_j=0/1$,当然把它看成边,注意到每个点度数不超过$2$,所以是若干个环和链,模拟即可。

Autobus

usaco好像也搬过这个。扫描线BiT或者分治一下。

Lustrzana pułapka

首先注意到我们只关心是否回到了原点,所以可以把反射改成取模,也就是从一个边界出去则从另一个边界回来,这相当于撞了一个边界就进行一次对称。这个看起来性质要好一些。接下来自然考虑把它无限延伸变成一条完整的射线,而原点被复制无限份,不过这个好像没太有必要。

设射到了$(a,b,c)$,那么我们称这是一步,则会在$\frac{\operatorname{lcm}(2x,a)\operatorname{lcm}(2y,b)\operatorname{lcm}(2z,c)}{abc}$步之后撞到原点。所以我们得到答案是$(a+b+c)\frac{\operatorname{lcm}(2x,a)\operatorname{lcm}(2y,b)\operatorname{lcm}(2z,c)}{abc}$。

但是还有一个小问题,就是这里射线不能碰到棱,所以还需要算一下。注意到我们要么永远不会撞到棱,要么在第一次撞到原点之前就会撞到棱。考虑前两维,如果存在$\frac{a}{b}=\frac{(2i+1)x}{(2j+1)y}$,也就是$2(jay-ibx)=bx-ay$,那么就会撞到棱。exgcd一下,我们知道这等价于$\gcd(ay,bx)\mid\frac{ay-bx}{2}$。注意到这个式子成立当且仅当$ay-bx=k\gcd(ay,bx)$中的$k$是偶数,那么$\frac{ay}{\gcd(ay,bx)},\frac{bx}{\gcd(ay,bx)}$不可能都是偶数,所以它们必然都是奇数,所以也就是$ay,bx$中$2$的幂次相同。

现在可以一个$\log$算一个点的答案了。考虑什么样的点可能有贡献,注意到如果$a,b,c$都选的很大,并且分别和$2x,2y,2z$互素,显然是很优的。如果$a,b,c$都很小,那么好像就比较的拉。选择$a=x-1,b=y-1,c=z-1$,答案至少是$(x+y+z-3)\frac{xyz}{8}$,如果想要进一步改善,$a,b,c$中有至少一个要和$x,y,z$对应互素。考虑$x$以内最大的和$2x$互素的数,发现它要么是$x-1$要么是$x-2$。但是很遗憾,这里还有一个限制,不过我们预处理一下哪些互素,然后分别往下枚举一些检查那个不能碰到棱就好了。看了一眼,三个分别往下枚举$12$个就过了。

Prawoskrętny wielbłąd

注意要回家的。

画一画观察一下,猜测一条路径合法,当且仅当每个角都合法,并且边的方向没有跨过$1\rightarrow 2$的方向,或者说只能转一圈。正确性还是比较显然的。

那么从$1$出发,把$2$作为$0$排一个极角序。现在开始dp。设$dp(i,j)$表示当前刚走了$i\rightarrow j$的答案,那么转移可以转移到$0\rightarrow j$和$i\rightarrow j$两个半平面bound住的一个部分。注意到固定$j$,则可以转移到的部分是$0\rightarrow j$右侧,$j$出发顺时针排极角序得到的一个后缀,所以对每个$j$开一个前缀和优化即可。复杂度$O(n^2\log n)$,瓶颈是排序。

XIII(2005~2006)

Stage 1

Okresy słów

border和周期一一对应,这里好像就是要找一个最短border,那就真的把所有border跑出来就好了。但是应该没有这么复杂啊?

考虑我们类似于kmp,设$f_i$是前缀$i$的最短border长度,先爆力向$f_{i-1}$中插入$i$,然后最短border的信息就都包含在前缀$f_i$中了,跳$f_{f_i}$就得到答案。复杂度$O(n)$。

Krążki

模拟。

Żaby

请注意这里是平面,距离是欧几里得距离。

最小瓶颈树是线性的,主要问题是要求到每个点最近的关键点。把式子写出来,发现它是一个二维的东西,看起来我们需要把它化成一维的。

试了一下发现好像不能类似 货币兑换 一样做,那么就是不能直接化成凸壳了。考虑怎么让它简单一点,注意到两维是独立的(你不会没有把根号扔掉吧?),所以先对每个点求出同一行的点中最近的,然后这个就变成了一个常数,再对每个点求同一列中最近的即可。总复杂度线性。

Tetris 3D

发现是矩形max矩形推平,然后这里max是单增的。满点集,四分树,复杂度$O(d^3)$,是不是就过了啊!

注意到并不是满点集,最大值必然在某个立方体的角上取得,所以只把这些点拿出来建2-dt,复杂度是$O(n\sqrt{n})$的。

由于max是单增的,也可以树套树俩$\log$。

Profesor Szu

没有环的话就dag dp。有环的话,只要可以走到环就是答案,所以从环出发倒着dfs即可。有向图找环,使用kosaraju或者tarjan scc。

Stage 2

Magazyn

当然切比雪夫转曼哈顿,然后就中位数了。转回来之后不一定是整数。

Szkoły

容易想到费用流,但是直接建的话边数是$n^2$的。哦network simplex是不是就过了啊?事实是,所有东西都过了。

由于$k$都不一样,看起来很难优化建图。

Metro

这里是允许交的。注意到我们每次必然是从已经选了的部分出发往边上扩展两条链,因为如果和已经选的部分不交,换一下就交了并且必然不劣。从一个直径端点出发长剖,选前$2l-1$长链。

Najazd

凸包上的差分,我们设$s(i,j)$表示从$i$顺时针转到$j$的区域中所有点的权值和。

Listonosz

我们把规定的一串边直接从起点连到终点。但是问题是,可能出现两个序列包含同一条边,所以需要先建一个空图把这些序列加进去,然后在上面dfs得到所有极长的序列,然后拿这些去跑。

Orka

考虑最后我们肯定会把一维全部删完,另一维则可以留一些不删。区间dp,设$dp_1(i,j)$表示第一维删到$[i,j]$,尽量删第二维,可以删到哪里。转移就往里删一步。

Stage 3

Tańce w kółkach

感觉小膜数很有用,所以先搞个式子。发现它就是$nz^n^k$,那么猜测$n$很大的话直接全膜成$0$了,想了想发现是真的,因为$p$出现至少$\lfloor\frac{n}{p}\rfloor$次,那么注意到$5^\frac{n}{5}401^\frac{n}{401}$增长的显然比$n$快多了,所以比如$n\leq 1000$爆力卷,更大的直接输出$0$即可。

Estetyczny tekst

dp,设$dp(i,j)$表示最后一段选了$[i,j]$的答案,转移考虑上一段,发现就是某个长度以内的绝对值是一边,以上的是另一边,那么我们双指针扫这个分界点,前缀和优化即可。

Kryształy

容易想到从高到低数位dp。注意到如果一个数不顶上界了,它就完全自由了,剩下的数不管怎么选,它都有唯一的方式把剩下的数调整成正确的。所以我们考虑在最先不顶上界的数处统计一个方案,如果有多个那就取编号最小的。

Misie

大力dp。

Palindromy

题意好像是,给若干个回文串,求其中有多少对接起来还是回文串。

枚举长的,那么短的需要是它的前缀,插个trie即可。

Zosia

发现这个有向边其实是无向边,所以就是求一个最大独立集。注意到一个连通图的最大独立集不超过点数的一半上取整,所以只有$O(k)$个点在非平凡连通块中,套用$1.1996^n$的最大独立集,复杂度在有且只有一个非平凡连通块,大小为$2k+1$时最劣,所以是$O(1.1996^{2k})$。

遗憾,这个题直接随一个顺序贪心就过了。

XIV(2006~2007)

Stage 1

Drzewa

考虑我们直接枚举换完之后的四个符号,得到四维偏序,然后仨$\log$排序分治分治BiT即可。需要特殊处理相邻的。

注意到我们要换的位置左右哪个大哪个小是没有关系的,所以就只剩下两维了,也就是对于$i$有$a_i<\min(a_{j-1},a_{j+1}),\min\leq a_i<\max,\max\leq a_i$,对$j$同理。

Biura

也就是在补图求连通块个数,怎么感觉已经出过这个了。考虑枚举一个点,如果它到前面某个点有边则标记不合并,然后把剩下的都合并了,复杂度线性。

Zapytania

经典。莫反。

Osie symetrii

所有的对称轴必然过重心,所以先找到重心,然后维护哈希值和中心对称之后的哈希值即可。

Atrakcje turystyczne

从每个关键点出发dij,然后状压dp。

Stage 2

Grzbiety i doliny

模拟。

Powódź

注意到每个最低的点组成的连通块显然需要放一个,所以从小到大放,模拟一下它排空了哪些点。但是可能你会从一个谷里跳过去,复杂度就飞了,这就很麻烦。发现这是瓶颈路,所以考虑从低往高扫,某种意义上是自底向上扫答案的kru重构树。

Skalniak

考虑了很多强行做法,但是不好优化。考虑如果一个方案中$x=y$两侧都有点,那么全都翻到$x=y$的一侧必然不会让周长变长,画一画你就发现这些边全都对应起来了。

于是考虑如何最小化重量和。我们可能会把一些东西翻回去,要想不让周长变长,只能是做刚才那样的翻折的逆,所以画一画一共有四种可能的答案。赢了。

Megalopolis

差分,问题变成子树加单点查询。

Tetris Attack

考虑直接从左往右扫,维护还未匹配的部分,加入一个的时候往前找,如果有就换到一块,感觉除了它没啥东西可以正确了。用BiT维护还剩多少即可。

Stage 3

Koleje

看起来是一个斯坦呐树。两倍让我们想起tsp的近似算法,考虑用任意dfs序近似最小斯坦呐树,于是从每个关键点跑dij即可。

Gazociągi

注意到每个点的贡献是确定的。

Odważniki

先全都除掉最小的那个。考虑这个东西相当于,每个容器的容量是一个奇怪进制的数,那么从低到高尝试消掉每个容器的每位即可。也就是如果有一个容器当前这一位非零,那就去放。如果物品用完了,就看下一位,否则尝试把下一位也填满,这里优先填下一位非零的。

据说可以直接把所有的容器不进位地加起来。

Egzamin na prawo jazdy

完全没有一个方向啊。考虑每条路能到一个区间,那么能到所有路当且仅当能到第一条和最后一条。同时,第一条路能被一个前缀到达,最后一条能被一个后缀到达,所以答案是一个区间。注意到能到第一条路是贪心往右走,能到最后一条是贪心往左走,两边是独立的,所以可以分别求出加$i$条边最远可以到哪,然后卷起来。

先考虑第一条,最后一条是类似的。看起来我比较智障,可以发现跑一个lis,不在lis中的位置就是需要加边的位置,然后就结束了。

Klocki

容易想到$n^2$,设$dp(i)$表示最后一个选了并且有贡献的是第$i$个的答案,那么$i$可以转移到$j$,当且仅当$j-i\geq a_j-a_i$,也就是$a_j-j\leq a_i-i$。BiT即可。

Waga czwórkowa

感觉很困难。还是考虑数位dp,设$dp(i,j)$表示高$i$位,$i$及以上还有$j$没有消去的最小个数和方案数,这里$j$是以$i$作为第$0$位记录的。注意到如果一位选了超过$4$个,那么也一定不优,如果一位同时被两边选了,那么也一定不优。主要问题是$j$可以多大,显然它不能超过$2\log_4 n$,当然这个还是太松了,可以猜测它的绝对值不超过$2$,因为低位最多只能凑一个无限接近$1$的数。

XV(2007~2008)

Stage 1

Klocki

枚举最后我们选的区间,那么肯定它们都要贴到中位数上去。对顶堆即可。

Plakatowanie

单调栈,贪心地,这看起来确实是最优的。

Cło

二分图匹配。

或者发现我们只要找到一个生成基环树森林即可,所以dfs然后随便再找一条边。

Szklana pułapka

感觉很离奇。首先由于这是光,我们只要找到从每个点出发会在哪结束。考虑不会有两个这样的过程在某一时刻状态相同,否则它们必然来自同一个起点。

洛谷上的翻译没提到周长很小。爆力找到边界上所有点,然后模拟即可。

Robinson

相当于把每个障碍物都变成中心对称的船的样子,然后船变成一个点。bfs即可。

但是这里有$2000$啊?考虑找到船的中心,然后我们希望每次都能真的把一个位置推成障碍,那么容易想到bitset,但是这里不太需要,考虑我们顺着船的方向扫,那么每个障碍是一个长度先变大再变小的区间推平,注意到投影在扫描线上同一个位置的障碍,同时只有一个在贡献,并且一个贡献结束了就不再贡献,双指针一下,然后差分-前缀和就赢了。复杂度$O(n^2)$。

Stage 2

Blokada

建个圆方树,然后直接结束。

BBB

枚举转了多少次,然后我们会把前若干个$-1$改成$+1$,后若干个$+1$改成$-1$。现在$n\log n$是简单的。

考虑类似于某个经典题,发现其实我们所要的就是前缀和的最小值,因为它变成正的了就全都变成正的了,并且它必然可以变成正的。单调队列即可。

Pociągi

爆力hash。对每个等价类维护一个大小,一共有$O(n+m)$个等价类,一个车相当于查询了一个区间$\max$,四毛子即可。另外最好写的区间半群是并查集。

Mafia

这是一个内向基环树森林。dp,如果是树,设$dp(u,0/1)$表示$u$能/不能活到开枪的答案,转移枚举每个儿子有没有开枪,如果有儿子开枪了那么$u$就可以死。现在有一个环,钦点一个人,从他身后断开即可。

Ucieczka

感觉很厉害。考虑只能往右拐说的是啥,发现我们接下来可以干啥会受到且仅受到前两次转弯时位置的影响,于是可能的状态数是$O(n^4)$。前缀和优化,直接冲,直接过。小问题是按什么顺序枚举,按两维的差枚举就行了,类似于区间dp。

Stage 3

Lampki

请注意颜色$k_i$只是一个说法,实际上它们是互不相同的。考虑crt,发现对于$i$,答案是$\displaystyle\frac{\prod_{j>i}(p_j-1)}{\prod_{j\geq i} p_j}$。

Kupno gruntu

容易想到$n^3$,也就是枚举一边,双指针另一边。猜测我们需要一些好性质。如果一个数$\geq k,\leq 2k$,那么可以直接选它。如果一个数$>2k$,那么不可能选它。现在每个数要么是障碍要么$<k$。考虑如果有一行的一个区间和$\geq k$,那么必然可以删一些数使得它$\leq 2k$,所以就赢了。但是答案可能不是行的区间,继续考虑这个想法,枚举$y$上的投影,我们得到若干个列的和,如果一列的和$\geq k,\leq 2k$,直接选,如果$>2k$则是障碍,那么问题是求障碍之间有没有一段的和$\geq k$。考虑固定这个投影的上端点,枚举下端点,那么我们可以知道每个位置何时变成障碍,在它变成障碍的时候分裂它所在的段。倒过来把分裂改成合并,并查集维护,复杂度$O(n^2\alpha n)$。

然后发现这个过于复杂。注意到如果一个矩形不包含$>2k$的数,并且它的总和$\geq k$,那么它的子矩形中必然有解。考虑如果有一行的和$>2k$,那么这一行一定有一个区间是解,否则一定有若干行组成一个解。单调栈求个最大权子矩形即可。

Podział królestwa

也就是求一个子集到另一个子集的边数。dp,复杂度$O(2^n)$。但是这个题卡空间,那就一边搜一边算。

具体地,也就是你要把一个点从一个集合移动到另一个集合,那么边数的变化量是简单的。为了从这个生成所有可能的状态,枚举所有$2^n$个状态,然后总共发生$O(2^n)$次切换。

Trójkąty

直接做。注意到叉积的式子是$(x_b-x_a)(y_c-y_a)-(y_b-y_a)(x_c-x_a)$,展开之后每一项只和两个点有关,不过外面还有一个绝对值,发现这个符号就是它的方向,所以就是半平面数点,枚举一个点,给剩下的排极角序扫过去即可。

Permutacja

感觉之前有场cf出过这个。如果这一位卡着,那么就卡着了,否则这一位放一个更小的,剩下的部分可以随便排,一个还有$c$次没有出现的元素的贡献是$\frac{1}{c!}$,那么所有更小的的贡献就是$\frac{1}{c!}+\frac{z}{(c-1)!}$,BiT维护前缀积即可。

膜数不是素数,crt,维护一个数的时候附带当前考虑的素数的次数即可。当要做加法的时候,必然是直接统计进答案了,所以可以直接转成整数。

Stacja

发现如果两个点只需要一张票,那么一个是另一个的祖先,那么省掉的票的总数就是每个点的深度和。直接换根dp即可。

XVI(2008~2009)

Stage 1

Straż pożarna

注意到到两个点距离相等的点是一条折线,大概是这个样子 :

img

那么边上的都矩形数点数掉了,主要问题是中间那个。考虑平时我们是怎么数任意多边形的,差分成一条斜线下方的部分和一个矩形,那么斜着扫,维护每个位置下方的点数即可,BiT。

Słonie

考虑每个位置不对的数至少要参与一次交换,分开考虑每个环,对于那个转一圈的构造,一个数要参与$n-1$次交换,剩下的每个数参与一次交换。那么我们显然希望最小的那个数贡献$n-1$次。考虑也可能会换环外的,那么我们希望全局最小贡献$n$次,这个环上每个数贡献一次。每个环对这两种取个$\min$即可。

Gaśnice

考虑了网络流,但是不凸,所以只好dp,但是dp也不会处理$s$。

考虑直接贪心,我们在尽可能高的地方放一个灭火器即可,也就是一个灭火器总是可以比它匹配的子树内最深的点高$k$。需要维护所有未被覆盖的点,每次取出其中最深的,然后维护子树中的灭火器。每次让尽可能深的灭火器匹配最深的未被覆盖的点。复杂度$O(nk)$。

Kamyki

考虑其差分,发现就是staircase nim。

Przyspieszenie algorytmu

也就是每次取$p$或者取$s$,用相同的调用序列取得的值的集合也相同。取出来的都是区间,所以我们直接会了多项式复杂度。

可以猜测,把连续段缩成一个,只保留每个数第一次出现和最后一次出现之后,两个序列相同那就是相同了。但是看样例发现假了。考虑取$p$就是删到第一次出现最右的数的第一次出现,取$s$就是删到最后一次出现最左的数的最后一次出现,但是注意到删的时候可能影响别的数的第一次和最后一次出现,这就完蛋了。

注意到颜色个数很少,考虑这玩意有没有什么用,首先这限制了状态数不超过$2^{100}$。/jy

考虑对于每个左端点,向右找到每个颜色个数增加的位置之前,反过来也是一样的,这样我们得到$O(nk)$个状态,猜测只有这些状态是可达的。考虑如果一个区间$[l,r]$,比如取了$p$,没有得到一个这样的区间,那么继续向右扩展,颜色个数仍然不变。

考虑直接搞出每个等价类。按颜色数从小到大处理,那么根据上一句话,我们已经知道取$p$取$s$分别会到哪里了,然后还需要限制取$p$删掉的那个字符相同,所以对于每个颜色数,给每个等价类分配一个编号,那么颜色数为$i$的就是颜色数为$i-1$的两个,和一个字符乘起来,基排然后离散化即可。复杂度$O(nk)$。

感觉我理解的很不深刻啊。

Stage 2

Przechadzka Bajtusia

从两边往中间dp,设$dp(i,j)$表示$i$到$j$的答案,转移枚举两条边,转移的复杂度是$\prod\limits_{i,j}\deg(i)\deg(j)=O(m^2)$,然后转移的边权都是$1$,队列维护即可。考虑能不能把同一个字符的边搞得快一点,字符只有$\Sigma=26$种,注意到枚举了一个字符之后,可以$O(n^2\Sigma)$地计算这个子矩阵$\min$之类的东西,因为它的一维是啥跟另一维没有关系,只跟这个字符有关。复杂度$O(n^2(n+\Sigma)+nm)$。

Konduktor

dp,设$dp(i,j,k)$表示这次在$i$检票,上次在$j$,总共用了$k$次的答案。

Architekci

感觉感觉。建立子序列自动机,那么需要求一个长$k$的路,贪心地转化成最长路长度是不是足够。那么从后往前扫,用可撤销化数组存转移,对不够长的位置开个BiT,够长的位置直接维护最大的,那么只有在后$k$个位置,以及前面的位置中最多$k$次会操作BiT,所以复杂度就是$O(n+k\log k)$。

或者看看题解,发现合法当且仅当我们第$i$次选了$[b_{i-1}+1,k-i+1]$之间一个数。单调队列维护第一个$\max$即可。

Łyżwy

hall定理。重温一下经典,考虑这个也就是每个人匹配一个长$d$的区间,要求人是否有一个完美匹配,那么也就是求任何一个人的集合是否满足邻接的鞋比人多,也就是求鞋数减去人数的$\min$,称这个是权值。注意到最小的集合必然是一个区间,因为如果我们从小到大排序,相邻两个人邻接的鞋不相交了,那么这就分成了两个集合,其中某一个必然不比另一个小;如果所有相邻两个人邻接的鞋都相交,那么把最左边到最右边的人中间全选上必然不劣。于是现在我们要求一个最小子段和,线段树即可。

Wyspy na trójkątnej sieci

主要问题是怎么编码一个这样的图。感觉上直接用每一步绝对的方向编码就行了(而不是记录你怎么转弯这种东西)。

Stage 3

Wiedźmak

dij。状态数是$2^pn$,大约是1e6。但是需要注意一下边数,是$2^pm$的,大约是2e7。考虑有没有一个简单的$O(1)$ decrease key的做法,感觉一下没有。考虑是否有一个顺序让我们不用decrease key,感觉一下把手中剑的状态相同的分为一层,那么一层内的边需要dij,层间的则不需要。于是我们的堆大小就是$O(m)$,感觉上很可过。

Słowa/Słowa 2

考虑如果是给你了一个串应该咋办,毕竟我通过$k=0,k=1$可以拼出所有串。类似于找到所有$10$和开头的$0$,它们必然由$1$得到。最后一个$1$在上一轮是$0$还是$1$不能确定,但是此外的$1$必然由$0$得到。如果有两个相邻的$0$,那就爆炸了。如果最后只剩一个字符了,那就可行。所以我们会了$O(2^m)$。

感觉一下,状态只有$O(m)$种,因为只有最后一位在变啊。

现在考虑各$k$任意怎么做。每个串内部啥样是确定了的,但是边界上可能有问题。注意到每个串前两个字符必然是$10$,最后一个可能是$1$也可能是$0$,除了$k=0,k=1$的情况。找到所有$k\geq 1$的串,爆力维护$k=0$的。如果一个串最后是$0$,那么需要判断它后面是不是$0$。如果它最后是$1$,后面有一个$0$,那么这个$1$就要被拿出来跟后面合并。那么每个串可能,正常,最后一个位置本来是$1$而变成$0$了,已经消失了,强行维护一下即可。

Tablice

妈的,怎么还元素互不相同的。直接多重集hash。

Wyspa

发现我们希望尽可能贴着$1\rightarrow n$走,然后这条路好像就是所有边的半平面交。看看这个半平面交怎么求啊,发现对每个点只需要找到最低的和它有边的点。

Kod

读错题。

看起来复杂度是$O(L)$,其中$L$是总长。

也就是给一个每个叶子代表一个串的$01$ trie,求有多少个串$a$满足,对于任意可能出现的编码的前缀$s$,$s+a$在trie上不停贪心匹配,到最后恰好匹配完。发现$s$具体是啥是没有用的,只有它最后停在哪个点有用,于是也就是在任何一个 从根出发,走某个编码的后缀,然后走某些编码 可以到达的点,走一个$a$都会到根(叶子和根是同一个点),那么爆力就是枚举一个起点,dfs地枚举一个串,复杂度$O(n^2)$。我们将 从根出发,走某个编码的后缀 可以到达的点称为关键的,将关键点走某些编码可以到达的点称为有效的。

考虑怎么找到所有关键点。找一个dfa匹配后缀,那么当然可以多串sam。或者考虑有没有什么$O(L)$的做法,考虑枚举一个点,处理它到子树中叶子的所有路径,也就是一边dfs子树一边同时dfs整个trie,这个东西复杂度是子树大小之和,看起来它是$O(L)$,因为子树大小不超过两倍的叶子数,而每个叶子会被算对应的串长次。

接下来找到所有有效点。注意到如果从一个关键点出发,经过根到达了一个有效点,那么这个有效点必然也是关键的,因为从根到它走的是一个串的后缀。所以每个关键点也只需要找到子树内的有效点。一边dfs整个trie一边同时dfs子树,如果离开了子树则剪掉即可。

接下来统计答案。对于所有有效点再类似地dfs,但是这次是如果到不了根则把这个字符标记为不行,如果到了根还没匹配完,则再递归到根,并记忆化一下。总复杂度$O(L)$。

Poszukiwania

可能没太看懂题意,说的大概是如果答案是yes则支付$1$,no则支付$2$?设$dp(i)$表示用$i$块钱可以搞定最长多长的区间。翻译比较奇怪,但是看起来$dp(0)=1,dp(i)=dp(i-1)+dp(i-2)$之类的。交互则记录转移。

XVII(2009~2010)

Stage 1

Kolej

每个栈必须是有序的。如果什么时候栈顶是接下来应该放的数,那么直接pop。现在考虑插入一个数,如果它比一边的栈顶小,比另一边大,那么当然插入这一边。如果比两边的都大,那么没救了。如果比两边的都小,这个是主要问题,猜测我们应该push进栈顶更小的那一边。但是这个看起来很假啊,因为有pop的话,我们可能会希望pop一串之后得到一个更大的栈顶,来放接下来比较大的一个数。

考虑一些强行做法。对于一个栈的情况,结论是如果存在$i<j<k$满足$a_k<a_i<a_j$,那么不可行。对于两个栈的情况,这里$a_k$是作为一个 不能进行pop 的限制,于是如果出现这种情况,$i,j$不能在同一个栈中。为了证明这是充要的,类似于一个栈的情况,我们知道在任意pop结束后的时刻,两个栈都是单调递减的,而递减就说明不会有数被卡死。

所以从后往前枚举一个$k$,在前面比$a_k$大的顺序对之间连边,然后二分图染色。于是也就是给若干个矩形的顺序对连了边。转而考虑两个点$i<j$之间何时有边,如果$a_i<a_j$,并且有$k>j,a_k<a_i$,那就有边了。于是找到$a_k<a_i$的最大的$k$,$i$向这个$3$-side矩形连边,主席树优化建图即可。

为了砍空间,考虑直接从下往上扫,扫到一个点的时候,它贡献了一个区间推平,如果两个推平冲突则无解,线段树维护即可。

Gildie

注意到我们不需要没有办事处的点,那么考虑随便找一棵生成树,奇数层分配裁,偶数层分配缝,就赢了。

Test na inteligencję

subsequence am,vector上二分找转移就好了。

Korale

hash。

Najdzielniejszy dzielnik

那么也就是求出现次数最多的素因数的出现次数。看起来并不能全pr一遍,所以我们就只分解三次根号以内的好了,看起来算量是4e7左右,然后开根,mr判一下,剩下的必然是两个素数的乘积。我们枚举每两个算它们的$\gcd$,就可以得到这些素数,然后试除一轮,可能还会剩下两个一起的,mr判一下,直接统计进答案即可,复杂度$O(n^3+nv^{\frac{1}{3}})$。

Stage 2

Antysymetria

由于它是对称的,可以manacher。或者二分hash。

Chomiki

考虑如果现在以$a$结尾,接下来再以$b$结尾需要的长度是确定的,因为保证了串互不包含,这个也就是求最长的$a$的后缀满足它是$b$的前缀,acam即可。然后矩阵快速幂即可。

Klocki

考虑什么时候一个区间合法,发现如果区间和$\geq k\cdot len$必然合法,如果不满足这个那么可能两边还可以救一救,但是发现答案必然没有被两边救,因为救完了之后算上两边就得到更长的区间。拆拆前缀和,大概是$s_i=\sum\limits_{j\leq i}(a_j-k)$,答案要满足$s_r-s_{l-1}\geq 0$,也就是$s_r\geq s_{l-1}$。单调栈即可。

Owce

强行dp,经典的,枚举一条边和这条边连向的点,那么划分出来的每个部分都是一个区间,然后就是三角形数点了。一共有$O(n^3)$个三角形,不过没有关系,使用经典的差分即可。需要排$n$次极角序,复杂度$O(n^3+nm\log m)$。

Teleporty

经典的,大力讨论,最后图有七层$1,S_1,S_2,M,T_2,T_1,2$,答案是所有相邻两层连成完全二分图,每层内部连成完全图。

Stage 3

Monotoniczność/Monotoniczność 2

看起来很带劲。设$dp(i,j)$表示是否存在以$i$结尾长度为$j$的子序列。发现只有$j\bmod{k}$有用,但是此时就需要记多长了,BiT一下,我们会$O(nk\log n)$了。

考虑怎么对每个$j$批量转移所有的$i$。画到平面上,考虑$<$怎么做,也就是每个点推平右上方所有点。感觉比较困难。

考虑怎么对每个$i$批量转移所有的$j$。对于$dp(k<i,j-1)$,如果$j-1,j$之间是个$<$,我们扫到$i$的时候只需要考虑$a_i$最小,且$dp(k,j-1)=1$的那个$k$。于是我们会$n^2$了,但是看起来很不够啊。

考虑有没有什么性质。强行猜测如果存在以$i$结尾长$j$的满足条件的子序列,那么必然存在长$j-1$的,然后啪的一下就做完了。但是遗憾,这个是假的,我只知道要么存在长$j-1$的要么存在长$j-2$的,但是不知道是啥结构。

考虑有没有什么别的性质。感觉比较厉害,强行猜测,虽然可行的$j$不一定连续,我们还是只需要维护最大的那个,设为$f(i)$。从左往右归纳,现在考虑到$i$,假设$j<i$的$f(j)$都是从前面的$f$中最大的那些转移来的,$p(k)$是$k$的最优决策点,设$j=p(i)$。我们尝试构造一个$i$结尾长度$>f(i)$,或长度$=f(i)$而转移到一个已经被归纳的情况的方案。设$p_{f(j)}=j,p_{f(j)-k}=p(p_{f(j)-k+1})$为$f(j)$对应的方案。

  • 如果$a_j=a_i$,在$f(j)$的方案中把最后的$j$换成$i$,得到的长度$\geq f(j)\geq f(i)$,而$f(j)$是从前面某个$f$转移来的。

  • 不妨设$a_j<a_i$,那么也就是说$f(i)-1,f(i)$之间的限制是$<$。还是考虑拿$j$凑个方案。

    • 若$a_{p_{f(i)-1}}<a_i$,还是可以在$f(j)$的方案中把最后的$j$换成$i$。

    • 否则$a_{p_{f(i)-1}}\geq a_i$,而$a_j<a_i$,于是$f(i)-1$到$f(j)$之间必然有一个限制是$>$,把$>$后面的位置换成$i$。

于是我们证明了,对于每个不从前面最长的状态转移得到的方案,都有一个从前面最长的状态转移得到的方案不比它劣。BiT维护一下即可。

Gra w minima

猜测每次被选的必然是一个前缀,前缀和优化dp。

为什么必然是前缀?考虑如果你选了一个前缀挖掉一些,那么对手下一步带上这些挖掉的地方不会更劣。

Latarnia

计算几何/jy,矩形反射得到矩形,所以大力模拟。但是好像会出来指数个矩形啊/yiw

Żabka

批量二分双指针求出转移到哪,然后倍增。

Jedynki

考虑直接算最左边的$1$后面是$0$的方案数,对应的最右边,然后减去只有一个$1$的。

首先描述如何计算两个这种表示的数的加减法,也就是讨论相加的两段分别是什么,以及前面有没有进位。看起来跟正常的加法是一致的。和的段数不超过段数的和。

然后开始计算这些方案数。简单地,只有一个$1$的方案数就是$n$的长度。

枚举最左边的$1$的位置,不管顶不顶上界,下一位有恰好一种方案,然后如果$n$开头是$10$,那么一开始会顶上界,方案数是$n$的后这些位,否则每一位都自由了,方案数是若干个$2$的幂,也就是一堆$1$加起来得到一串$1$。

右边看起来要困难一点,枚举最右边$1$的位置,左边是若干个$n$的前缀加起来。不过没有关系,考虑每个位置的贡献,发现第$i$位是$\sum\limits_{k=0}^i 2^k=2^{i+1}-1$,当然如果是$0$则没有贡献,所以也就是整个数乘$2$再减去$1$的个数。模拟即可。

Mosty

二分答案,然后有的边两个方向都能走,考虑用网络流给边定向。只考虑已经确定方向的边,每个点有一个入度和出度的差,把这个差搞成$0$就胜利了,同时我们知道度数,所以一个点应该有几条未定向的边指向它是确定的,匹配一下即可。复杂度$O(m\sqrt{m}\log n)$。

Piloci

首先可以枚举左端点二分。左端点从左往右,右端点也从左往右,所以可以两个单调队列。

XVIII(2010~2011)

Stage 1

Lizak

容易想到法,但是这里必要不大。考虑枚举区间长度$k$,然后把所有数都减去$1$,问题是有没有一个长$k$的区间有给定个$0$,那么发现每次加入一个$0$删除一个$0$,$1$的个数是连续变化的,所以求出最小值和最大值即可。

想了想你发现最小值和最大值好像也不是那么好求。那么也就根本不要这么做,设$s_i$表示$i$位置的后缀和,找到第一个$1$,设它在$p$,那么所有以$p$或$p+1$为左端点的区间拼成了$[1,s_i]$,那么完全在$p$右边的区间都已经没有用了。同理找到最后一个$1$。现在还剩下端点在第一个$1$左边,最后一个$1$右边的部分,它们是这两个$1$之间的和,加上若干个$2$。

Piorunochron

classic。在洛谷上你可能需要搜这个题的英文名 lightning conductor。

Przekładanka

也就是有两个环。这个题在arc出现过,看起来任意置换都可以换出来。但是想了想你发现逆序对数不对的不行。

感觉一下,注意到前三个就是某种窗口,a操作的作用是移动这个窗口,于是冒泡即可。但是有操作数限制,再感觉一下大概是不会爆的。

需要特判$n\leq 3$。

Konspiracja

注意是划分。那么如果两个人之间有一条边,他们就不能都在第一组,如果没有边则不能都在第二组,这个是充要的。考虑2-sat。结束了。

但是2-sat怎么计数啊?感觉很困难。考虑有没有啥性质。

考虑设第一组的大小是$k$,那么它合法,当且仅当第一组中所有点的度数之和是$m+\binom{k}{2}$。然后发现度数之和总是不可能比这个大,所以我们只需要考虑度数最大的$k$个点,如果可行,考虑其中度数最小的那些,尝试把它们换成一些度数相等的,组合数选一选即可。

Wykres

二分答案,然后向右贪心,但是随机增量需要你的顺序是随机的,所以我们先倍增地找到这一段大概的长度,然后在里面二分,复杂度$O(n\log^2 n)$。

Stage 2

Sejf

考虑对于最小的生成元$g$,整个群都是它的倍数,这里没有发生取膜。考虑我们可以辗转相减,所以如果有$a,b$则必然有$\gcd(a,b)$,那么最小的生成元必然整除剩下的所有数,否则取一个$\gcd$就得到更小的。

所以枚举这个最小的生成元$g$,它必然是$m_k$的因数,然后判断$m_1,…,m_{k-1}$中是否存在一个数是$g$的倍数,然后还需要它有可能是最小的生成元,看起来这个只需要当且仅当它也是$n$的因数,所以枚举$\gcd(n,m_k)$的因数即可。1e14以内最大的$d$在2e4左右,看起来不太行啊。

把每个素因数分开考虑,那么$m_1,…,m_{k-1}$每个数的作用相当于把各维都$\leq$某些数的位置给ban掉了。于是我们打个标记并做前缀和,这个前缀和是每一维前缀和的卡笛尔积,复杂度是$O((k\log\log v+d(v))\omega(v)+\sqrt{v})$。

另一个做法是把$\gcd(m_i,\gcd(m_k,n))$相同的数只留一个,据说得到的状态数会很少,经典的,$n$以内$k$-smooth数的个数,在$k$很小的时候近似为$\frac{1}{\pi(k)}\prod\limits_{p\leq k}\frac{\log n}{\log p}$,但是

Różnica

这个 出现过的 听起来就很困难。

注意到是极差,我们可以放成任意两个的差,然后你就会了$O(n\Sigma^2)$,也就是枚举最小的和最大的,赋成$\pm 1$求最大子段和,这里初值需要找到上一个字符的上一次出现,或者你可以拆前缀和。显然只需要在我们枚举的字符里面做,所以复杂度是$O(n\Sigma)$的。

Śmieci

也就是指定了每条边经过奇数次还是偶数次。我们可以且只能自由地给一个环的经过次数$+1$,要得到一个每个点度数都是偶数的,那么容易想到线性基,如果给的这些经过奇数次的边组成的向量在图的环空间中,那么就可以搞出来。所以跑一个dfs树找到所有非树边确定的环也就是基本环,它们组成一个环空间的基,我们可以把这些非树边换到前面来变成一个单位矩阵拼上一些可能是任何东西的树边的部分,所以也就是说我们把非树边搞对就赢了。然后差分一下找到每条边最后应该经过多少次,跑欧拉回路分解即可。使用四毛子lca,复杂度是线性的。

又看了看发现完全不对啊,给一个环的经过次数$+1$其实没有改变度数的奇偶性,也就是说我们保留所有经过奇数次的边直接跑欧拉回路即可。太智障了。

Rotacje na drzewie

注意到一个点换或者不换的贡献,跟子树中做了啥操作是没关系的,所以我们只是要求出换或者不换的贡献。这个是经典线段树合并,这里我们放了一个数的时候需要求它在另一棵树上的前缀和,带着这个前缀和递归下去即可,递归到只剩一边的时候就乘上子树中数的个数贡献进答案。

Temperatura

不太习惯poi说明部分分,我还以为整个题都$v\leq 50$。不过关系不大,dp,设$dp(i,j)$表示结尾于$i$,$i$的温度是$j$的答案,转移枚举上一个的温度,也就是推平为前缀$\max$,然后全局$+1$,并把比$l$小的和比$r$大的扔了。

那么你发现它总是单调的,这个推平其实啥用没有,所以用一个双端队列维护这些段就行了。

Stage 3

Dynamit

二分然后自底向上贪心,如果子树中有一个点距离为$k$的点还没被覆盖,那就在这个点上放一个。注意到未被覆盖的点中只有最远的有用。

然后需要考虑如果一个点有多棵子树,一棵子树放了的东西如何影响另一棵,我们只需要维护最近的放了的点。然后找到所有放了的东西里面最近的那个,看它能不能推掉所有没覆盖的里面最远的,如果不能就要在这个点放一个了。

另一个等价的做法是,按深度从大到小扫,每次找到一个还未覆盖的点,就在上面放一个,并标记所有被它新覆盖的点,每条边只会来回贡献两次,所以每轮复杂度是线性的。

Impreza

考虑如果两个点之间没有边,那么其中至少一个必然不在团中,注意到$\frac{2}{3}-\frac{1}{3}=\frac{1}{3}$,于是我们每次找到一对没有边的点删掉,剩下的就是答案。

Inspekcja

感受一下,只有所有子树大小都不超过$\frac{n}{2}$才行,也就是说最多只有两个点行。

Okresowość

考虑转成border,那么所有border的信息都被最长真border包括了,所以求出最长真border递归下去即可。但是如果最长真border长度不超过一半,那么中间会空一些,直接猜测判断如果目前是全$0$,则在最右边填一个$1$,否则填全$0$。为了证明这东西的正确性,画一画你发现如果填全$0$不行,根据定义当且仅当全$0$产生了新的周期,考虑一下,如果有一个周期长度不超过中间这一段,那么整个串都是$0$,此时在中间那一段最右边填一个$1$,剩下的还是$0$必然是可行的。

否则,先弱周期引理一下,设我们想要的那个最长真border的长度是$k$,那么它对应的周期长度是$n-k$,新产生的周期中最短的那个长度是$t$,那么$\gcd(n-k,t)$也是周期,如果它不比$n-2k$小那就没救了,然后你发现$\gcd(n-k,t)$

所以两边都是全$0$,。感觉挺对啊。

Meteory

过于经典。

Patyczki

考虑如果我们确定了两个短边,则只要找到某个区间中的三个出现过的颜色,使用st表,复杂度$O(n^2)$。

考虑怎么只带一个$n$,我们枚举最长边,设它的长度是$k$,以及另两条边的颜色,设它们的长度(还未确定)是$x,y$,那么要满足$x+y\geq k,x-y\leq k,y-x\leq k$。于是相当于问两个集合的笛卡尔积中,一个斜着的3-side矩形中是否有点。

画一画你发现这个查询看起来其实比较简单,它是查了一个有宽度的后缀,那么我们还是只需要一个斜着的单调栈,这部分排序双指针即可,总复杂度$O(nk^2)$。

优化也是简单的,我们只枚举一条边的颜色,然后单调栈的时候维护另一条边的两个特例,也就是考虑我们在画一条分界线的话,向左下走直到出现两个不同的颜色再向$x=y$贴近即可。复杂度$O(nk)$。

遗憾的,有远简单的做法。注意到如果固定了两条短边,那么长边我们肯定选最短的比它俩都长并且颜色不同的。于是我们排序后向下找到前两个颜色不同的,向上找到前两个颜色不同的,就赢了。

那么怎么找呢,直接扫过去,对每个颜色的最后一次出现维护一个堆即可。复杂度$O(n\log n)$。

Konkurs programistyczny

感觉好像很经典啊。

首先我们要匹配一下。然后要最小化这个罚时,洛谷翻译没说罚时是通过时间之和,呃发现这个相当于有个凸的费用,所以多加点边即可。

那么复杂度是啥呢。这个图有$n$个点$n^2$条边。发现死了。

注意到它再怎么说还是一个右部点的单重匹配,也就是说只有$n$条边有$1$的流量。如果我们能只更新这些边之类的就赢了。

想了想发现比较智障。不停跑一个最大匹配就赢了。这里我强力猜测复杂度是$O(n^{2.5})$,反正肯定不满。

XIX(2011~2012)

Stage 1

Festyn

这个看起来比较牛逼了。

首先可以差分约束一下得到是否有解。但是感觉这个没有必要。

考虑先把差确定的缩起来,我们对每个块钦点其中最小的作为代表元,那么一个块覆盖了$[x,x+a]$这样的。两个块之间的限制会是$x+c\leq y+d$这样的。于是可以推出一个形如$x-y\in[l,r]$的东西。其中$l,r$都有可能是无穷。如果$[l,r]$是空那就没救。

$x-y$有一个限制,$y-z$有一个限制,可以得到$x-z$的一个限制。考虑一下,如果两个块之间这样得到所有可能限制并合并,仍然有至少一侧的限制是无穷,那么无论如何都可以把它俩错开。无穷的方向也就是边的方向,于是我们跑一个scc,此时每个scc内部排好了,scc之间按照拓扑序放在数轴上即可。

于是考虑一个scc怎么做。由于这是scc,我们可以选一个主元表示每个所在的区间,这个对上下界分别跑floyd即可,然后问题就是给一些区间,每个区间的左端点有一个区间的限制,摆在数轴上使得覆盖的总长度最大。考虑贪心,按限制的左端点从左往右考虑,放在第一个还没被覆盖的位置。

然后发现我比较智障。由于这是scc,其中的值不管怎么分配都是连续的,简单归纳就可以说明这件事。于是只需要找到最大值即可。

Litery

classic。

Studnia

考虑如果没有这个需要挖到$0$的限制该怎么做。发现好像不是很会啊。

看成可以$\pm 1$了,想了一年slope trick,但是它不凸。

那么只能$-1$怎么做呢。二分个答案$d$先。考虑如果相邻两个数相差$>d$,必然让大的那个变小,于是就简简单单了。注意到从左往右扫一遍,如果$a_i+d<a_{i+1}$则$a_{i+1}\leftarrow a_i+d$,就可以解决答案中所有形如/的坡,因为我们必然先扫到坡底,而坡底左边根据归纳假设不会再变小(要么是形如\的坡的坡底;要么是形如/的坡的坡顶,已经处理过了;要么不属于任何坡)。于是两边各扫一遍就赢了。

那么现在需要挖到$0$了。把一个位置$p$挖到$0$,也就是把它两边bound成\/这样,注意到这个bound和上一步先做哪个都可以,于是我们做完上一步就只需要二分这个了。考虑左边,也就是在一个前缀中求$a_i\leq dp-di$的最大的$i$,那么维护前缀$a_i-di$的有序数组即可。直接注意到$a_i+di$和$dp$不降就赢了。

Randka

也就是求一个内向基环树上的lca。看看是不是属于环上同一个点的子树,树的部分直接lca,环的部分只有两种可能。

Odległość

也就是求一个曼哈顿距离最小的。大力分解先。

考虑每个数挂到它的所有因数,然后就赢了。复杂度$O(v\log v)$。

Stage 2

Tour de Bajtocja

感觉很难做。可以猜个结论,连接两个$>k$的点的边必然可以不删,因为删一条至少一个端点$\leq k$的边也可以断掉和它相关的一个环,而由于这是无向图,如果和它相关的环超过一个,可以想象一下大概比较有道理啊。剩下的就是图拟阵了,贪心,并查集维护即可。

Bony

爆力。

Szatnia

爆力是$O(\frac{qkn}{w})$。膜一个素数算方案数,莫队是$O(kn\sqrt{q})$。

考虑换一个顺序。判定性的东西都是可以提到前面来的,我们对每个$a$的前缀,求出位置最大的$b$的后缀使得背包有解。设$dp(i,j)$表示考虑所有$a<i$的元素,要凑出$j$,位置最大的$b$的后缀是哪一个,没有则是$0$。可以从$dp(i-1,j)$转移来,或者枚举所有$a=i$的元素。复杂度$O(nk)$。

Okropny wiersz

跑出runs。对于每次查询,首先枚举长度的因数,然后看有没有这个因数长度的run覆盖这个位置。一共有$O(n)$个run和$O(qd(n))$次查询,离线扫描线,总复杂度$O(n\log n+qd(n))$。

注意到如果$a$是非平凡整周期,$b$是非平凡整周期,那么$\gcd(a,b)$也是整周期。于是我们可以从$len$出发每次删去一个素因数,而删的顺序是无关紧要的,这样我们会得到$\log$轮查询,每轮有$q$个,但是每个run要塞到它的倍数去。根据the runs theorem我们知道这样塞出来的总数还是$O(n)$,所以还是离线扫描线,复杂度就是$O((n+q)\log n)$了。

考虑能不能不用runs。我们需要判断 $d$是不是$[l,r]$的整周期,同时我们知道 $pd$是$[l,r]$的整周期,那么实际上只需要判断 $d$是不是$[l,l+pd)$的整周期。对于$p>K$,$d$不超过$\frac{n}{K}$,可以一起扫一遍,这样的事情只会发生$O(q\log_K n)$次,扫的时候总要花费$O(\frac{n^2}{K})$;否则我们直接爆力hash,这部分是$O(qK)$。$K=\Theta(\frac{n}{\sqrt{q}})$时平衡,复杂度$O(n\sqrt{q})$。

然后发现我是智障。check一个周期等价于check一个border。复杂度$O((n+q)\log n)$。

Rozkład Fibonacciego

加加减减还是很带劲。先考虑几个简单的事情 : 答案不超过$\log_{\hat{\phi}} n+O(1)$。如果相邻两个fib数贡献都非$0$,那么我们可以把它们合并。$3f_n=f_{n+2}+f_{n-2}$,而$3f_1=f_4$,也就是说任何一个数系数的绝对值不会超过$2$,也就是说超过一位的退位就没救了。可以继续考虑到$2f_n=f_{n+1}+f_{n-2}$,也就是说任何一个数系数的绝对值不会超过$1$,证明的话让我们定义势能是每一位的位置乘上系数的绝对值的和,显然它非负,并且每次使用$2f_n=f_{n+1}+f_{n-2}$都会减小。

这自然让我们考虑一个问题 : 如何给出若干个fib数和的zeckendorf表示。一个简单的$n\log v$是用$3f_n=f_{n+2}+f_{n-2}$把最大值折掉$\frac{1}{3}$,边界处用$2f_n=f_{n+1}+f_{n-2}$递归更新。

于是在zeckendorf表示上dp,设$dp(i,j)$表示从高往低考虑到第$i$位,上面的退位是$j$,系数的绝对值之和最小是多少。感觉上$j$只可能是$\pm f_{i+2},\pm f_{i+1},0$中的一个,甚至可能$f_{i+2}$是取不到的,这就很带劲了。

题解做法比较厉害,直接找到最接近$k$的$f_n$然后取差,dp都不用了。洛谷题解证的很好。

Stage 3

Squarki

首先可以得到最小的两个数的和。最大的也是可以的。

这个解数看起来很困难,于是更加考虑能不能找到什么性质。

排序。考虑原序列排序后是$a_1,…,a_n$,那么这个和的第一位必然是$a_1+a_2$,第二位必然是$a_1+a_3$,第三位可能是$a_1+a_4$或$a_2+a_3$,这就麻烦喽。不过没有关系,我们知道了$a_1+a_2,a_1+a_3$,就知道$a_2-a_3$了。考虑怎么确定任何一个数,枚举$a_2+a_3$是哪一个,比$a_2+a_3$小的必然是$a_1+a_k$这样的,于是也就是枚举最大的这样的$k$,此时我们就知道了$a_1,a_2,…,a_k$。然后我们就知道了所有的$a_i+a_j(i,j\leq k)$,而剩下的里面最小的必然是$a_1+a_{k+1}$,这样下去就全知道了。复杂度$O(n^3)$。

Licytacja

也就是谁达到$x+y\geq n$谁就赢了。

一共只有$82$个$x$。搜即可。

Pensje

感觉很离奇。

对每个点求出上面最近的确定了的点和到它的距离,并考虑到有些值已经出现过,那么我们知道这个点的值就是某个前缀。把没有确定的点挂在这个前缀,已经确定的挂在已经确定的位置,此时如果一个前缀$k$挂了至少$k$个点,它和后面就分开了。如果一段中有且只有一个位置是不确定的,就可以确定它。一段内的值是可以交换的,因此它们并不能被确定,因此我们确定了所有可能确定的,这就证明了它的正确性。

Wyrównywanie terenu

恐怖极了兄弟。

也就是我们把每个数表示成$ax_i+by_i$,那么答案就是$x,y$分别做这个问题 : 有一个可能有负数的序列,每次可以给一个区间+1或-1,求最小的操作次数把所有数都变成0。考虑差分,相当于每次把一个移给另一个,要把整个序列变成$0$。可以发现答案就是差分的绝对值的和的一半。

首先对每个数exgcd求出一组解。然后我们可以$x_i\leftarrow x_i+k\frac{b}{g},y_i\leftarrow y_i-k\frac{a}{g}$生成所有解,其中$g=\gcd(a,b)$。也就是说要在若干斜率相同的直线上各选一个整点串起来,最后答案是在开头结尾各放一个$(0,0)$,相邻两个的曼哈顿距离之和。

注意到如果我们移动了$i$,$>i$的部分可以一样地移动,也就是说这不会改变后面的贡献。那么贪心让相邻两个最近即可。

但是实际上这会改变后面的贡献,因为最后需要回到$0$。考虑怎么把这个扔掉,如果可以像积木大赛一样,只算正的,并保证最后一个是负的那就赢了,但是这里允许只算正的就会不停选负的导致最后剩下的还是正的。这就没救了。

这是一道计算几何直觉题。考虑一个离奇想法,我们先做这个不管最后一段的,然后如果最后一段不优,再把它调整回来。如果相邻两个点是$(x_1,y_1),(x_2,y_2)$,最后一个点是$(p,q)$,判断移动$(x_2,y_2)$一步是否能减小答案即可。容易感觉到最多一共移动$n$步,因为我们跑出去的距离本来就不会太远,且两个位置的移动是独立的,我们选择使答案增大最少的$n$次前面的移动,依次计算总的答案即可。

Bezpieczeństwo minimalistyczne

看起来比较的有趣。

考虑每条边就是一个限制$a_u+a_v=k$。注意到对于每个连通块,确定一个就确定了所有的;如果有一个奇环,那么最多有一种可能。

假设图是连通的。如果不是二分图,则设一个是$x$,随便找一棵dfs树推出所有的,并解出$x$;如果是二分图,还是设一个$x$推出所有的,此时可以得到一个区间的限制,比如如果一个点初始点权是$a$,最后是$kx+b$,那就要求$kx+b\leq a$,这里$k=\pm 1$。可能还要求了减完的点权也非负吧,那就还有一个$kx+b\geq 0$。最后就是$x\in[l,r]$。由于每个点点权的减少量也是$x$的一次函数,我们知道两端必然分别取最大值和最小值。

Hurtownia

不凸,所以不是费用流。

容易考虑dp,但是感觉很困难。

考虑如果进货都在购买前,我们就从小到大选。

猜测还是从小到大选。如果不是从小到大选,那就会出现扫到某刻,我们不选$b_i$而选$b_j>b_i$,其中$b_i,b_j$排名相邻。如果$i>j$显然选$b_i$,如果$i<j$,那么我们就需要置出前面一个,而前面的都更小所以必然不优。BiT维护即可。

Prefiksufiks

对每个前缀求出最小表示,每个后缀求出最小表示,前缀爆力维护significant suffix就是$O(n\log n)$,后缀则是线性的。这才1e6直接冲了。

可以比较容易地线性。循环同构border就是$st…ts$这样的。那么我们先枚举一个border $s$,问题就是求删掉它后剩下的里面的长度不超过一半的最长border $t$。

考虑从中间往两边扫。注意到如果$[l,r]$有border $[l,p]$,那么$[l+1,r-1]$有border $[l+1,p-1]$。于是如果$[l+1,r-1]$的长度不超过一半的最长border长$k$,$[l,r]$的长度就不超过$k+2$,于是这里有一个均摊,用hash check一下即可。

还有一个牛逼trick!注意到因为我们删去的是border,两边的长度是相等的,我们把这个串重新排成$s_1s_ns_2s_{n-1}s_3s_{n-2}…$,那么border就变成了回文。

XX(2012~2013)

Stage 1

Usuwanka

考虑如果我们可以找到连续的$k+1$个可以消除的,那就消除它们,然后两边接起来。最后倒着输出,由于正着看中间的都是消掉的,倒着看中间的就都是没消掉的。

猜测我们真的可以找到。证明考虑每$k+1$个一块,如果没有一块包含恰好一个黑色,必然有至少一块只包含白色,并且这样的块里面必然有至少一个和一个包含黑色的块相邻。每次操作之后只需要重构$O(1)$块。复杂度线性。

然而实际上只需要开个栈就好了。

Cennik

如果$b\geq a$,那是好做的,只需要给每个点的邻接点们,挂个虚点优化建图即可。

如果$b<a$。那么此时考虑一个点$u$,我们需要只给$u$邻接点中没有边的点对两两连边。

一个想法是考虑把邻接点之间的邻接矩阵画出来,然后数据结构优化建图。具体地,考虑一行,也就是$v$到各$w$的边,存在$v\rightarrow w$的$w$会把这一行分成若干段,如果有$k$段我们就要连向$k$个区间。这里面每条边会出现两次。但是有问题。一条边会出现多个点的优化建图中。这就需要我们深入分析一下,如果一个点度数是$d$,那么它会产生一个不超过$\min(d^2,m)$的贡献,那么总共就不超过$O(m\sqrt{m})$。现在我们可以用一个$O(1)$向区间连边的东西,st表即可。复杂度$O(m\sqrt{m})$。

但是这里我们有$2m\sqrt{m}$条边,空间飞了。这就不好。

让我们看看题解怎么做的。首先发现这个$b$的所有用处就是如果一条路中两条相邻的$a$不能替换成一条$a$,则可以把它们替换成一条$b$。先跑一个最短路,那么最短路中相邻的两条边肯定不能替换成一条边,我们尝试尽可能替换成$b$,如果最短路长度是偶数,那么答案必然要么是全$a$,要么是全$b$的;如果是奇数,我们就会剩一个$a$替换不了,此时可能会希望选择一个长偶数的,第$2k-1,2k$条边不能替换成一条的最短路,然后全部替换成$b$。

那么这个东西怎么跑呢。看起来就是挖掉所有三元环。考虑到这是bfs,搜到一个点之后就不再需要它作为距离$=2$的点了。注意到三元环只有$O(m\sqrt{m})$个,考虑如果现在处理$u$,我们标记$u$的邻接点,然后枚举$u$的邻接点$v$,枚举$v$的还未访问的邻接点$w$,如果存在$u\leftrightarrow w$,那就跳过$w$,否则更新$w$,并在所有点第二层枚举的边表中删掉它。这样每个三元环会贡献$O(1)$次,复杂度$O(m\sqrt{m})$。

Gobeliny

每个限制bound出了一个多边形区域,我们需要求一个交。

这个太离谱了,考虑点简单做法。如果没有暗墙,这是一个经典的半平面交问题。注意到对于一段连续的暗墙$M$,设两边的顶点是$A,B$,那么$AB$和$M$围起来的区域都是暗的,也必然只有这样的区域是暗的,并且光源必然在直线$AB$上。所以把所有连续的暗墙的两端连起来跑半平面交,然后判断光源的范围(可能是一个点或一条直线)是否和半平面交有交即可,这也可以直接塞进半平面交来实现。或者可以 如果是点,直接检查一遍;如果是直线,把每个半平面拍到这条直线上变成$\geq x$和$\leq x$。

下面是第一遍的考虑。

如果有暗墙,考虑一段暗墙和两边的亮墙相接的地方,设这两个点是$A,B$,那么画一画可以发现由于多边形是连续的,光源必然在$AB$上。于是如果有两段暗墙就可以确定光源的位置。

先考虑如何check一个光源。我们向每个顶点发射射线,经过一个顶点则标记射线的这一侧被挡住了,离开了多边形则停下。如果离开时撞到边,如果有至少一侧还没有被挡住就无解。如果撞到点,标记这个点一侧亮另一侧暗。看起来实现复杂。

那么我们考虑只有一段暗墙怎么做。把$AB$连起来记为亮墙,然后判断半平面交和$AB$是否有交即可。

Taksówki

分为从$0$到$d$和从$d$到$m$两段。

到$m$最多需要一辆单独的车。任何一辆足够行驶$m-d$的车都可以。

到$d$的过程,看起来我们会让所有车从大到小出发。如果只剩下一辆足够行驶$m-d$的车,需要判断它能不能把你送到,不能的话则从$<m-d$的里面再派。

Multidrink

看起来很厉害。

首先方案倒着还是方案。首先找到$1\rightarrow n$这条链,想象我们从左往右走。会需要进入子树。比如链上有一个点$u$,它左边是$l$右边是$r$,且有儿子$v_1,v_2,…$,那么一旦从$u$进入$v_1$子树,离开的时候必然站在$v_1$,因为$u$已经走过了。也就是说我们进入的时候必然选择$v_1$的某个儿子,从它走到$v_1$。注意到如果有子树$v_2$,由于$u$已经走过了,我们进去只可能踩$v_2$,这导致我们出不来,所以不能有子树$v_2$,也就是链上每个点只能挂一个儿子。

考虑子树内。现在有一棵树,我们站在根$u$的儿子$v$上,要遍历整棵树最后到$u$。那么我们类似地知道如果$u$只有$v$一个儿子,我们就递归到$u$的某个儿子;如果$u$还有恰好一个儿子$w$,那么$v$必须是一个单点,否则一旦向下进入它儿子的子树,上来的时候就只能到$u$,而$w$还没有被遍历。于是我们知道$u$的儿子必须是若干个单点和一个任意的什么东西。然后考察这个任意的什么东西,继续讨论可以发现它必须是一个菊花。

现在我们解决了站在$u$上的问题。如果我们站在$l$上,可以直接进入一个儿子,此时还需要更多的讨论。这实在是太困难了,让我们dp吧!

设$dp(u,0/1/2)$表示$u$子树,从$u$进从儿子出/从儿子进从$u$出/从儿子进从儿子出 的方案是否可行,然后在链上从左往右再写一个dp。看起来还是很复杂。反正这就是个复杂题/oh

Stage 2

Spacer

两个01串之间怎么到达呢。注意到$k$只有1e6,我们从两个串出发分别搜出连通块中1e7个串,如果都能搜出来我们就断定连通,因为此时再断开它很困难啦。

草,我居然直接猜出题解。感觉很厉害。

具体一点是只需要搜$nk+1$个点。证起来比较困难。

Inspektor

看起来很困难。按时间排序先,然后有记录的人第一条和最后一条就确定了一个区间,先把它们覆盖一次。接下来如果一个人比如左侧的记录不满,那就让他往左一步,如果左侧还不满那就继续往左,这个可以用线段树维护。剩下的用没出现过的人积木大赛。这个只能跑判定,所以二分一下就好了,复杂度$O(n\log^2 n)$。

足有5e6,不得不砍砍你的$\log$。考虑怎么把线段树省掉,发现类似于积木大赛的单调栈证明来做就赢了。具体地,如果当前这一位限制是$h$,前面有$c$个能用的右端点,如果$c>h$则$c\leftarrow h$,因为超过的部分不能延申过来了;如果$c<h$则要右边的左端点来补充。维护一个单调栈,把$h-c$插入进去,弹掉的部分喂给积木大赛。当我们遇到一个能用的左端点时,对单调栈进行一个全局减,维护全局标记即可,可能需要弹掉栈底,所以实际上这是一个队列了。这就可以线性地check。

看了一眼题解。遇到左端点的部分可以认为是前面先喂给了积木大赛,然后这个左端点把它接上了。于是这个单调栈也没有用了,弹的时候就对应于,先尝试限制右端点的部分,如果还没弹够就继续限制积木大赛的部分。

Łuk triumfalny

显然B不会走回头路。考虑一个类似于超现实数的想法,dp,设$dp(u)$表示B站在$u$,$u$是黑的而子树其它点都是白的,只考虑$u$子树的情况对应的数,那么B可以选择向任何一个儿子走,而A必须把所有儿子都操作到$\leq 0$才能获胜。于是也就是$dp(u)=\max(0,\sum\limits_{v\in\operatorname{ch}(u)}(dp(v)+1)-k)$。二分即可。

Konewka

线段树维护一下$<k$的$\max$,如果有$=k$的就找出来标记。

Morskie opowieści

感觉好像很眼熟啊。考虑我们总可以在一条边上横跳,所以拆点分别跑长奇数和偶数的最短路即可。

Stage 3

Gra Tower Defense

直接随便选一个还没被覆盖的点就是对的,因为在那个存在的解中每个点要么是塔要么和塔相邻,所以随便选一个点必然到某个塔距离不超过$1$,因此覆盖了这个塔所覆盖的。

问题是怎么找覆盖了哪些点。维护每个点到最近的塔的距离,爆力更新即可。复杂度是线性的。

Bajtokomputer

看起来比较厉害。简单想法是从左往右找到第一个$1$,然后右边都结束了。于是我们也知道没有必要产生一个$>1$的数。用dp确定$-1,0,1$三段分界的位置即可。$-1$段从开头的极长连续$-1$开始,$0$段必须只包含一开始就是$0$的,$1$段从一个$1$开始。

Gdzie jest jedynka?

总是只需要一次比较。爆力是用$n^2$次$d=n-1$的查询找到$1,n$,然后用一次比较确定哪个是$1$。

考虑如何优化。我们随便找一个数,和它差最大的数要么是$1$要么是$n$。大力试除可以$O(\frac{n}{\log n})$地得到一个数。但是这个看起来比较困难啊。

考虑一个牛逼想法。我们维护一对相距最远的点,从第$\lg n$轮开始往下进行,第$i$轮让它们往两边扩展$2^i$,如果某一侧不能扩展则不扩展(假装自己扩展了)。但是这里有一个问题,我们不能判断距离是否$=2^i$,这还是比较难受。不过不需要判断这个,如果上一轮最后两个点距离是$k2^{i+1}=2k2^i$,我们去找那个距离为$(2k+1)2^i$的即可。这样扩展一轮是$O(n)$的。此时我们会得到最多六个点,在其中爆力找到相距最远的两个继续进行,直到它们的距离为$n$,这里求距离是$O(\frac{n}{2^i})$的,没有必要再除一个$\log$了。总复杂度$O(n\log n)$。

考虑了怎么确定剩下所有数。看起来是无法做到$O(n\log n)$的。

Łańcuch kolorowy

对前缀桶进行字符串hash,那么区间桶的hash就是两个前缀桶的差。

Labirynt

什么惊悚题。

看了一眼题解,感觉很厉害。大概是说,我们首先选出四个L作为顶点,要满足顶点之间LR个数相同,此时顶点之间可以看成一条很粗的边,为了避免碰撞,两头搞到足够长就可以了。然后要搞定每条边内部。假设第一位是L,那么找到第一个R满足它们之间LR个数相同,这可以用桶找到。递归搞定里面,外面接上这一个L一个R得到的还是一条边,然后再把它跟后面接起来。复杂度线性。

Laser

每条线段也就是一个极角区间。把所有点排极角序,每个间隔需要处理出如果射线射在这里,经过多少线段,以及经过的线段中最远的端点,然后就是选$k$个不交的区间使得权值和最大,前缀和优化dp即可。复杂度$O(n(k+\log n))$。

这个题同时是cf16 exhibition final I

Polaryzacja

考虑最小值。二分图染色,每条边从黑点连向白点,这样答案是$n-1$。显然答案不可能更小。

考虑最大值。比较困难。dp个先,设$dp(u,i,j)$表示$u$子树,$u$能到的有$i$个,能到$u$的有$j$个的答案。复杂度$O(n^3)$。转移的时候$i,j$只有一个有用,可以把空间压到$O(n^2)$。

这个最大值比较厉害。结论是我们找到重心,让一些子树指向重心,剩下的子树从重心发出,答案就是内部的加上两部分的大小乘积。背包一下使得两部分的大小尽可能接近。复杂度$O(n\frac{\sqrt{n}}{w})$。

如何证明这件事呢。考虑先证明必然有一个点是一些子树指向它,剩下的子树从它发出。

断言存在一个这样的点,当且仅当所有极长链有交,当且仅当不存在四个点$u,v,a,b$满足$u\rightarrow a,u\rightsquigarrow v,b\rightarrow v$。那么考虑存在这样的$u,v,a,b$时,以$u\rightarrow v$为根将树拎起来,设$i_a,o_a$为$a$子树中能到达$a$/$a$能到达的点数,那么这两端原本的贡献是$o_a+o_b$。翻转$a,b$子树中所有边和$u\rightarrow a,b\rightarrow v$,贡献变成$\geq o_a+o_b+o_ao_b$,必然不劣。

然后证明这个点必然是重心。如果它不是重心,不妨假设最大的子树,大小为$s$,且指向它,那么把它向最大的子树移动一步,指向它的部分大小$c$不会变大,而如果$c>\frac{n-1}{2}$,$c$越小子树间的贡献越大,因此答案不会变小。

XXI(2013~2014)

Stage 1

Wąż

强力dp。

官方题解以一种不错的方式描述了这个题的结构。这里有一个deepl机翻。

Klocki

如果没有两边的颜色,我们能放最多的就放最多的,不能就随便放一个,相同数量按数值为第二关键字排序。注意到这样可以保证如果两边颜色可以不同,那么构造出来就是不同的,于是如果两边的颜色限制不同也赢了。

如果两边的颜色限制相同,我们把这个颜色拿出来作为”随便放一个”的唯一候选,直到把它用完。

看一眼题解,这玩意能线性。拿个链表即可。

Hotele

classic。

考虑如何线性。对于某三个点,按深度从大到小是$u,v,w$,center是$c$,它们到$c$的距离都是$d$。长剖,在$c$处统计每个$d$的$u,v$对数,然后把它挂到所有祖先上,对于$k$级祖先,要一个距离$d-k$的点作为$w$,这可以在一个上传的数组上打一个标记。

设$f(u,i)$是$u$子树距离$u$为$i$的点数,$g(u,i)$是$u$子树lca为$u$的距离为$i$的点对数,$h(u,i)$是$u$子树中所有在$u$上要一个距离$i$的点的标记,那么$f$就是儿子们$f$的和平移一位,$g$就是$[t^2]\prod(1+tF)$,$h$就是平移一位再加上这里的$g$。$g$的长度不超过最长的轻儿子的长度,于是$g$合并到$h$的复杂度就摊给了这个轻儿子。

Kurierzy

classic。

Bar sałatkowy

还是看成$\pm 1$保证和非负吧。如果总和是$s$,那么$i$位的前缀和$l_i$和$i+1$位的后缀和$r_{i+1}$满足$l_i+r_{i+1}=s$,要求$r_{i+1}$非负也即要求$s-l_i$非负,也即$l_i\leq s$。

设全局的前缀和是$p$,考虑区间$[l,r]$,那么$s=p_r-p_{l-1},0=p_{l-1}-p_{l-1},l_i=p_i-p_{l-1},0\leq l_i\leq s\Leftrightarrow p_{l-1}\leq p_i\leq p_r$。也就是求有多少区间$[l,r]$满足$p_l,p_r$分别是区间$\min,\max$。

枚举$l$,那么右侧的非严格单调栈上都满足$p_r$是区间$\max$,而$l$在一个前缀是区间$\min$,二分即可。这个前缀可以用另一个单调栈求出。

考虑如何线性。瓶颈在于二分 右侧递减单调栈的第一个元素在递增单调栈中的前驱,考虑分散层叠,我们用链表维护两个单调栈(右侧递增和递减)的归并即可。

Stage 2

Karty

如果只问一次,贪心。

线段树。对于每个区间,维护第一位的卡是正面/反面时,最后一位的卡应该是正面还是反面。

Przestępcy

如果没有这个起点颜色相同的限制,直接跑两遍子序列自动机,复杂度$O(n\log n)$。

如果有的话,考虑枚举中间这个位置,往两边倒着匹配,留出尽可能长的前后缀,看其中有没有相同的颜色。

注意到每个颜色出现最多一次,这里就有均摊了,以左边为例,从左往右枚举中间,尝试最后一位的匹配位置能不能右移,如果可以则继续尝试倒数第二位,这样的。由于每个颜色只会扫过一遍,复杂度是线性。

剩下的问题就是怎么看一对前后缀有没有相同颜色。开个桶,如果从左往右扫,从右往左撤销后缀的桶即可。

Superkomputer

牛逼题。

曾经出现在21年sd省队胡策的qc赛。

大致译自 https://fajnezadania.wordpress.com/2014/04/13/superkomputer/ 。

倒过来变成剥叶子。这有一个好处,我们剥一个叶子不会让叶子的数量增加,只会让它不变或减少$1$。

那么首先我们知道如果现在叶子数$\leq k$,所需的轮数就是树的高度。如果叶子数$\geq k$,我们每次必然选满$k$个。

由于叶子的数量不会增加,而到了叶子数$=k$的时候答案就确定了,一个贪心的想法就是先剥最深的叶子使得树高尽可能减小。但是这样有可能会使得叶子数更快地减小。

考虑枚举最优解中叶子数$=k$时的树高$h$。设$c_h$是$\geq h$的所有层的点数和,那么我们至少需要$\lceil\frac{c_{h+1}}{k}\rceil$轮才能剥完它们,接下来还需要$h$轮结束。但是直接这么估计是有问题的,因为我们并不一定每次都剥了一个深度$>h$的点。不过注意到$\lceil\frac{c_{h+1}}{k}\rceil$是轮数的一个下界,我们把所有东西都取一个$\max$得到一个更紧的下界。接下来证明这个贪心达到了这个下界,从而同时证明它就是答案。

考虑我们选择了深度最大的$k$个叶子,有深度相同的则任意选。设其中最浅的那个的深度是$d$,树高是$H$。如果$h<d$,那么$h+\lceil\frac{c_{h+1}}{k}\rceil$显然减少了$1$。如果$h\geq d$,那么$h+\lceil\frac{c_{h+1}}{k}\rceil$可能不变,于是我们希望说明它必然不是原来的$\max$。由于选择了深度为$d$的叶子,$>d$的每一层点数都$<k$,因为每一层的点数都不超过下一层点数加上这一层叶子数,在这一轮操作前后都是这样的。于是我们知道对于$h\geq d$,$h+\lceil\frac{c_{h+1}}{k}\rceil\leq h+1+\lceil\frac{c_{h+2}}{k}\rceil$,这是因为$h+1$层的点数$<k$。于是$\max\limits_{d\leq h\leq H}h+\lceil\frac{c_{h+1}}{k}\rceil=H$。既然$H$减小了$1$,我们知道$\max\limits_h h+\lceil\frac{c_{h+1}}{k}\rceil$就减小了$1$。

剩下的问题是如何对每个$k$求$\max\limits_h h+\lceil\frac{c_{h+1}}{k}\rceil$。考虑怎么把取整去掉,我们把$h$塞进去,就变成$\max\limits_h \lceil\frac{hk+c_{h+1}}{k}\rceil=\lceil\max\limits_h \frac{hk+c_{h+1}}{k}\rceil$。也就是有一堆一次函数$h+c_{h+1}x$了。为了使用凸壳,转而考虑有一些点$(-c_{h+1},h)$,用斜率为$x$的直线去截,截距即为$h+c_{h+1}x$。要求截距的最大值,求上凸壳然后扫过去即可。复杂度$O(n)$。

感觉在这个问题上倒着性质确实更好。

Ptaszek

classic。

dp。$dp(i)=\min\limits_{j=i-k}^{i-1} dp(j)+[a_j\leq a_i]$。容易想到线段树,但是不行。

注意到这里代价只有$0,1$,那么存在一个最优决策只使用$dp(j)$最小的某个$j$,维护$dp$为第一关键字,$a$为第二关键字的单调队列即可,也就是dp相同的保留$a$最大的这样的。

Rajd

感觉很眼熟。原来是出现在sdptt2021 r1的讲课环节。

考虑排个拓扑序,那么删一个点,以它前面的点结尾的路径不会被影响,以它后面的点开头的路径不会被影响。两部分各自内部是容易线性的。两部分之间的边$u\rightarrow v$会产生$f(u)+g(v)+1$的贡献,在$u$处加入$v$处删除,离线并查集可以做到$O(m\alpha(n))$。

Stage 3

FarmerCraft

看到farmer就条件反射了,poi玩usaco模拟器是吧/cf

dp,设$dp(u)$表示$0$时刻进入$u$子树的话,最后一个装完的时间。转移考虑进入各子树的顺序,每个子树有遍历时间$a$和代价$b$两个参数,答案是$\max\limits_i b_i+\sum\limits_{j<i}a_j$。容易想到邻项交换。设前面的和是$s$,相邻两个是$(a_1,b_1),(a_2,b_2)$,对后面的影响相同,对答案的贡献是$s+\max(b_1,a_1+b_2)$。要凑$\max(b_1,a_1+b_2)\leq \max(b_2,a_2+b_1)$。考虑怎么才能拆出来。

  • 如果$b_1\leq a_1+b_2$,那么也就是$a_1+b_2\leq\max(b_2,a_2+b_1)$,由于$a_1+b_2>b_2$,也就是$a_1+b_2\leq a_2+b_1$。

  • 否则也就是$b_1\leq \max(b_2,a_2+b_1)$,必然成立。

合起来也就是如果$b_1-a_1\geq b_2-a_2$,那么$(a_1,b_1)$排在前面。

Dookoła świata

感觉有点眼熟。看起来某次学校的模拟赛出现过。

爆力就是枚举一个起点然后贪心,如果$O(n)$地预处理,可以$O(c)$地处理一个有$c$次加油的方案。注意到如果我们从$p_1$出发依次经过的序列是$p$,那么从任何$p_k$出发还是经过$p$。考虑随便找一个位置出发求一个$p$,那么对于任意一个$k$,任意一个贪心求出的方案必然经过$[p_k,p_{k+1})$中的某个位置。于是在最短的$[p_k,p_{k+1})$中枚举一个起点即可。

为了证明这东西的复杂度,我们证明如果$l$的总和是$s$,则每个方案的加油次数都在$[\frac{s}{d},2\frac{s}{d}]$中。下界是显然的。对于上界,考虑对于每次加油,设上次加油到这次加油的幻想距离为 加油前已经跑过的距离 加上 它面前的这一段,由于贪心,幻想距离是$\geq d$的。考虑所有的幻想距离的和,由于每一段最多算两次,这个和不超过$2s$,而每一次加油至少跑了$d$的幻想距离,所以最多加$2\frac{s}{d}$次油。$\Theta(\frac{s}{d})$段点数的平均值是$\Theta(\frac{nd}{s})$,那么必然有一段是$O(\frac{nd}{s})$的,贪心一次复杂度是$\Theta(\frac{s}{d})$,因此在这一段中枚举起点就得到复杂度$O(n)$。

也可以不枚举起点。注意到各个起点的方案不会相互穿过,所以我们这么扩展,把重合了的只保留一个,复杂度是一样的。

Mrowisko

以食蚁兽为根把树提起来,问题就是求一个到根的乘积喽。基排双指针就结束了。

Turystyka

也就是直径$\leq 10$的图求最小权支配集。

直径很小的图看起来就很有趣。考虑随便跑一棵dfs树,那么树的直径不超过$10$。由于这是dfs树,非树边只可能是返祖边,也就是说子树间互不影响,这就很好。

dp。设$dp(u,S)$表示$u$子树,到根的链的状态是$S$,子树内的答案。复杂度$O(2^{10}n)$。

Lampy słoneczne

范围是相同的,角度不超过$180$,想象一下也就是说能照到是传递的。显然这东西形成了一棵树。

主要问题是如何把树建出来,建完之后dfs一遍就好了。看起来还是自底向上比较阳间。沿角平分线方向扫我们得到一个拓扑序。角是两个半平面的交,判定是否在照射范围内只需要知道沿这两个半平面垂线方向的位置,离散化先,剩下的问题就是给一个点集,支持激活一个点,删除一个2-side矩形中所有激活的点。树套树即可。

看一眼题解没想到就是这个复杂度。树套树太拉了,考虑如何卡常。注意到很可以离线。首先这里外层树可以BiT。内层树问题是序列,支持在某个位置插入一个点,或者清空整个后缀,还是可以BiT。所以就$O(n\log n)$空间了。

Panele słoneczne

感觉比较厉害。

考虑$d$是$[a,b]$中某个数的因数,当且仅当$\lfloor\frac{a}{d}\rfloor>\lfloor\frac{b-1}{d}\rfloor$。$\lfloor\frac{a}{d}\rfloor$分成$O(\sqrt{v})$段,那么$\lfloor\frac{a}{d}\rfloor>\lfloor\frac{b-1}{d}\rfloor$也分成$O(\sqrt{v})$段,那么$[\lfloor\frac{a}{d}\rfloor>\lfloor\frac{b-1}{d}\rfloor][\lfloor\frac{c}{d}\rfloor>\lfloor\frac{d-1}{d}\rfloor]$也分成$O(\sqrt{v})$段,整除分块即可。

妈的,怎么还有多测。现在我们还有八倍常数,砍砍你的。考虑我们只需要找到最右的那一段,所以倒着扫感觉就会得到一个$\frac{1}{2}$的常数。

Załadunek

感觉很厉害。考虑我们必然是上连续发若干班,然后下把它们发回来,这样的,中间可能会有什么都不做的时间。dp,设$dp(i)$表示前$i$班完全结束的最小时间,转移枚举刚才这一串,如果是$(j,i]$

  • 如果在$k$时刻发$i$,那么就在$k-(i-j-1)$时刻发$j+1$,于是我们要求$k-l\geq t_{i-l}$,且上一轮在$k-(i-j-1)$时刻前结束,于是$k=\max(\max\limits_l(t_{i-l}+l),dp(j)+i-j-1)$。

  • $i$发出后需要经过$s$时间到,然后才能发返回的车,也就是共经过$2s+i-j-1$时间。

于是$dp(i)=\min\limits_j \max(\max\limits_l t_{i-l}+l,dp(j)+i-j-1)+2s+i-j-1$。注意到两列车同时来,其中一列必不可能立刻发,让它延后$1$不影响答案,所以可以让每个$t_i$跟$t_{i-1}+1$取$\max$,此时$\max\limits_l t_{i-l}+l=t_i$。

对$\max$讨论,显然$dp(j)-j$单增(从$dp(j)$的方案少发最后一班可以得到$dp(j-1)$的方案),双指针维护$\max$切换的位置,单调队列即可。

XXII(2014~2015)

Stage 1

Czarnoksiężnicy okrągłego stołu

假设$p=3$。可以感觉到合法序列整体上还是双调的。从$n$往两边dp。注意到两边具体到哪是不重要的,只有填了多少是重要的,设$dp(i,S,T)$表示填了前$i$个数,左右状态分别是$S,T$的方案数,考虑$S$是啥样的,$T$是对称的。$S$需要从第一个空位右边一位开始,往左记录所有信息。预处理所有可能出现的状态及转移即可。

当两边接起来的时候需要爆搜。

然后感觉我比较的拉。考虑插入而不是摆放,我们现在要放$i+1$,记录$i$和$i-1$,$i-1$和$i-2$,$i$和$i-2$是否相邻,如果相邻的话顺序是什么。见于 https://www.cnblogs.com/chenxiaoran666/p/Luogu3581.html 。

Kwadraty

容易感觉到这个$k$大概是三次根号级别的。

首先只有有限个数不能被凑出来。

1
2 3 6 7 8 11 12 15 18 19 22 23 24 27 28 31 32 33 43 44 47 48 60 67 72 76 92 96 108 112 128

我们要求的是一个从无穷远处来的非严格后缀$\min$个数。看起来它还是挺大的。

在1e6处$k=144$。1e6以内$k$分成$5360$段,这看起来不是很能用。

既然这个东西可以快速求,我们首先猜测怎么求。简单想法是这个方案就是贪心选最大的。但是这个不对。

注意到$a^2=(a+1)^2-2a-1$。既然$>128$的数都能凑出来,我们可以要求前面选的若干个都是连续的,把这个$-2a-1$扔给后面解决。猜测减到$128$以内的前一步这个数不大,至少我们可以知道$\frac{2}{3}$次的界。考虑如果这个数很大,我们把$k$减小$1$,会腾出$\Theta(k^2)$来,啊啊,还是不是很好啊。

不过没有关系,我们猜测找到最小的$t$使得$S_{n^3}(t)\geq n$,那么$k(n)$要么是$t$要么是$t+1$。这个也只对有限个数是错的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
n k t
64 8 6
68 8 6
73 8 6
80 8 6
97 9 7
107 9 7
132 9 7
137 9 7
157 10 8
173 10 8
177 10 8
189 10 8
193 10 8
257 11 9
273 11 9
277 11 9
378 12 10

考虑每个$t+1$后面有至少一个$t$,也就是$k(S_{n^3}(t))=t$,那么剩下的问题就是求有多少个$t+1$。

如果我们想凑出$n$,可以先选一个$S_{n^3}(t)$,然后凑$S_{n^3}(t)-n$并把这部分减掉。可以注意到$S_{n^3}(t)-n=O(n^\frac{2}{3})$,于是这个事情只有在$S_{n^3}(t(n))-n$是一个不能被凑出来的数时才可能不能做到。打表发现当$n$足够大时这是充要的,于是结束了,复杂度$O(\log n)$。

Pieczęć

模拟。容易想到纸上最左的,如果有多个则取最上的格子必然是由最左的,如果有多个则取最上的格子印出来的,如此sort之后扫过去模拟一下即可。

Kinoman

画到平面上,出现$c$次的颜色贡献$O(c)$个矩形,2-side矩形加,最后求全局$\max$,扫描线线段树即可。

Łasuchy

如果这是链。如果现在决策$i$,我们需要知道$i-1$会不会反悔,于是记$i-1,i-2$的选择即可。

现在这是环。枚举$1,2$的选择。

那么接下来让我们看看牛逼做法。考虑如果存在相邻两个食物满足一个比另一个的一半还要小,那么它俩夹的这个人肯定选另一个了。此时这个 另一个 的值就减半,我们dfs地找到所有这样的选择。如果这样的选择一个都没有,我们转一圈显然是对的。如果有至少一个,此时剩下了一条链,找到一个最小值,它左边往左右边往右即可。

Stage 2

Logistyka

感觉很眼熟。如果模拟的话,我们每次都会选最大的$c$个。但是这个模拟看起来性质不是很好。

题解比较厉害。考虑这个$s$是有其意义的,我们把操作的轮数看作横轴,把操作的元素看作纵轴,那么问题是每一列不能有重复的,于是考虑扫行,如果一个元素超过$s$个,超过的部分肯定没救,否则让它填到未完成的行里,如果填满了就另起一行,这样每一列显然没有重复的。也就是说把每个数跟$s$取$\min$之后总和$\geq cs$那就可以。BiT维护即可。

Podział naszyjnika

还是画到平面上。可行区域是一些矩形并的交,我们希望求一个离$y-x=\frac{n}{2}$最近的点。每个矩形并看起来是一个左上2-side矩形和一些右下2-side矩形,这两部分是没有交的。于是对两部分分开处理,左上直接求对$x,y$限制的交,右下从左往右扫$x=y$,求出每个点上对$x,y$分别的限制的交,只看$x$就是区间对左端点取$\max$,最后求整个序列,画一画发现单调栈即可。复杂度$O(n)$。

让我们看看题解。看起来有个牛逼做法,给每个数随机权值使得每个颜色的xor和是$0$,那么区间合法当且仅当xor和是$0$。hash table,每个桶开个双指针即可。

Pustynia

我年轻的时候居然还做过这个。显然toposort,需要用个啥优化建图,看起来就是从这些数连到一个虚点,从虚点连到区间中剩下的数,线段树即可。

Kurs szybkiego czytania

感觉这个比较有趣啊。还是按照惯例称为$s,t$。考虑从$s$入手,$t_j=1$当且仅当$aj+b\bmod{n}<p$,可以看成是限制了$j$在环上的一部分,那么设出起始位置的值$x$,$s$的限制就是若干个环上的一部分的交。因为$a\perp n$,每个数出现恰好一次,所以最后交出来的区间长度就是答案。呃呃,因为实际上它还是序列,需要减去匹配位置$>n-m$的部分。

Trzy Wieże

这个大概比较有趣啊。只有一种字符的情况直接处理掉。只有两种字符的情况,发现认为第三种字符出现$0$次是没有问题的。于是问题变成求$i,j$使得前缀和数组的差中没有两个数相同且$i-j$最大。

尝试爆力地思考。如果$[l,n],[l,n-1],…,[l,k]$都不满足要求,并且$k$足够小($k<n-O(1)$即可),那么这之间三种颜色的出现次数的极差不超过$1$,且必然在$O(1)$步内达到一个三种颜色出现次数相等的状态,接下来每三步都是三种颜色各一个。如果某三步不是这样了,那么立刻就会出现一个答案。于是处理每个位置往后不停选三种颜色各一个的三步到何处停止即可,复杂度$O(n)$。

然后根据这个可以证明答案要么左端点在$[1,3]$要么右端点在$[n-2,n]$。

Stage 3

Odwiedziny

看起来是容易归约到任意查询的。于是根号分治,如果$c\leq K=\Theta(\sqrt{n})$我们预处理每个$c$下到根的前缀和,求出$\mathrm{lca}$之后跳一次la来减去多余的贡献,否则爆力长剖la。复杂度$O((n+q)\sqrt{n})$。

Myjnie

最便宜的一个比较呃呃。考虑如何避免记录单调栈。

考虑扫值域,我们找到全局$\min$,然后把包含它的确定下来,那么画到平面上发现可以区间dp了。设$dp(i,j,k)$表示区间$[i,j]$,最小值$\geq k$的答案,那么我们枚举这个$\min$的位置和值,处理跨过$\min$的区间,然后递归下去,复杂度$O(n^3m^2)$。注意到可以前缀和优化,或者可以直接不记$k$,因为如果枚举的$\min<k$我们只会把这个方案的答案算小,复杂度变为$O(n^3m)$。

Tablice kierunkowe

如果行列的多重集分别形成相同的多重集则可行,那么hash然后排序即可。

如果元素可以相同,感觉是npc的。

Wilcze doły

显然我们会修改长度恰好为$d$的区间。枚举这个区间然后向两边延伸,但是因为不凸看起来不是很好办。考虑枚举答案,固定一个端点的话另一个端点显然是单调的,因此可以双指针,那么问题变成维护区间长$d$的最大子段和,单调队列即可。复杂度$O(n)$。

Kolekcjoner Bajtemonów

题意大概是,有一个序列,除了某个颜色出现次数较少,其它所有颜色出现次数相同,求出这个较少的颜色,只能读一次,卡空间。

这个题看起来还是比较有趣啊。求出这个相同的出现次数$c$,这可以通过维护两个特例的出现次数做到。同时维护二进制每一位的出现次数,那么膜$c$之后就得到答案。

Modernizacja autostrady

对于最长。枚举这条边,然后把两边的直径串起来,也就是最大化两边的直径和。为了求子树外,四毛子lca。

对于最短。显然切了一条边之后我们必然连两边的center,如果两边的直径分别是$l_1,l_2$,那么连起来之后是$\max(l_1,l_2,\lceil\frac{l_1}{2}\rceil+\lceil\frac{l_2}{2}\rceil+1)$。我们肯定要切断直径上的一条边,如果直径超过一条,如果center是一条边我们必然切center,否则切啥都没用。如果直径唯一,那么我们随便切一条边之后,两个直径端点必然分别是两边的直径端点之一,可以用那个dfs求直径的结论来证明。那么问题就是以直径为根拎起来,求每个点子树中的最长链,然后胡乱统计答案即可,这里不需要lca。总复杂度$O(n)$。

对于最长也可以不需要四毛子lca。如果没有断直径上的边,以直径为根求子树直径,然后加起来即可。如果断了直径上的边,跟最短一样做。

Wycieczki

又来k短路了。啊啊,怎么$k$有1e18啊?

于是矩阵快速幂。倍增,如果总路径数超过了$k$就停下。直接在乘法里面判断是不是超过了$k$。复杂度$O((nv)^3\log k)$。

XXIII(2015~2016)

Stage I

Hydrorozgrywka

怎么poi也有仙人掌题。在圆方树上换根dp,进入环时可以选择顺时针走或者逆时针走,环对外面的影响只需要一个bool。

Park wodny

统计每个B的连通块,枚举一个连它周围最大的两个即可。

Nim z utrudnieniem

我们需要把xor和搞成$0$,于是设原来的xor和是$k$,这就是$[z^kt^0]\prod(1+z^{a_i}t)\bmod{t^d-1}$,其中$t$上是普通卷积而$z$上是xor卷积。那么问题就是法哇塔怎么卷上一个$(1+cz^S)$这样的东西了!

题解比较牛逼。考虑爆力dp,设$dp(i,j,k)$表示前$i$个,xor和为$j$,选的个数膜$d$是$k$的方案数,从小到大排序,注意到$\operatorname{highbit}(j)\leq \operatorname{highbit}(a_i)$,于是总状态数就是$d\sum a_i$的。

Nadajniki

大力dp。设$dp(u,i,j,k)$表示$u$子树,$u$放了$i$个,$u$到儿子们的边中差的最多的还差$j$个(也就是$u$的父亲至少放这么多),$u$的儿子们放了$k$个(这限制$u$的父边是否满足条件)的答案,显然每一维都不超过$2$。转移的时候枚举$u$放了几个,$u$的父亲放了几个,儿子们放了几个,此时儿子们就独立了,然后在儿子之间背包即可。

Korale

如果只求权值和,经典做法是从空开始扩展,把珠子从小到大排序,每次可以选择当前方案中最后一个的下一个,或者把最后一个换成它的下一个,复杂度$O(n\log n)$。每个方案只有一种扩展出来的方法,所以不需要记忆化。

另一个想法是,二分答案,然后直接这么扩展$k$个。复杂度是$O(k\log v)$。

要求字典序最小的方案的话,我们就需要比较字典序了。可以感觉到每个方案中元素个数都很少……吗?注意到一个方案的子集都比它小,所以任何方案不超过$\log k$个元素,复杂度$O(k\log^2 k)$。

感觉这里需要更厉害的东西。我们写这么一个堆,每次要比较两个权值和相同的方案时,就把它俩合并,然后递归下去合并子树,这样我们弹的时候必然是把权值和相同的方案一口气弹完了。达到答案的时候我们要给一些方案排序,使用基数排序做到$O(k\log k)$。

但是这个是错的!因为这个扩展并不一定能搜到答案。考虑我们拿着权值和去搜这个答案,贪心选择字典序最小的方案使得权值和仍然$\leq$答案即可。为了做到这个需要知道一个后缀中$\leq$某个数的数中最靠前的,在线段树上二分即可。

Stage II

Świąteczny łańcuch

经典题。我们是要一个连通块个数。把所有区间对的长度拆成$2^k$,这里它是幂等的所以像st表一样拆即可。然后对于长度相同的区间,如果$[l_1,r_1]\leftrightarrow [l_2,r_2]\leftrightarrow [l_3,r_3]$,那么现在再来$[l_1,r_1]\leftrightarrow[l_3,r_3]$就没有意义了,所以只需要保留左端点间的一棵生成树,这样就只剩$O(n)$条边。把它们再拆成两半递归到下一层。复杂度$O(n\log n)$。

Drogi zmiennokierunkowe

看起来很带劲。首先缩scc,那么同一个scc要么都行要么都不行。问题变成在dag上找一个点使得它可以到达的和可以到达它的点的并是所有点。求能到的点数,practical的做法是$O(\frac{nm}{w})$,看起来并不行。

可以注意到一个点满足条件当且仅当它在拓扑序中的位置确定,因为如果$u,v$互不可达,我们删掉所有可以到达$u,v$中至少一个的点之后就可以删$u,v$中任何一个。于是考虑能不能求出最大位置和最小位置啊?但是这个还是等价于统计每个点可达的点数。我们需要一个让问题再弱一点的性质。

考虑我们把所有在拓扑序上跨过了$u$的边都删掉,那么$u$前面的点到后面就必须经过$u$了,并且删掉这些边对$u$能到的点集和能到$u$的点集并没有影响。考虑前面,此时如果$u$前面一个点没有出度,那就显然没救。否则由于每个点都有出度,而$u$前面的点一直走下去必然经过$u$,所以$u$前面的点都能到$u$。后面同理。复杂度是线性的。

感觉这个题还是比较有趣。

Zająknięcia

首先注意到不弱于lcs。

dp,设$dp(i,j)$表示两边分别匹配到$i,j$这样的,那么如果$a_i=b_j$,我们可以从$a_i,b_j$分别的上一次出现$-1$转移来,这俩分别记为$t_a(i),t_b(i)$吧。但是卡空间。

感觉这个题会比较厉害啊。注意到比如我们先扫第一维,如果我们现在扫到$i$,那么我们只会从$(t_a(i),j^\prime)$转移来,其中$b_{j^\prime}=a_i$。于是每个颜色只有出现次数个状态是有用的,空间就是线性的了。但是这玩意不用卡常?但是这玩意不用卡常?但是这玩意不用卡常?但是这玩意不用卡常?但是这玩意不用卡常?

一看时限10s。行。

Arkanoid

看起来有点惊悚了。考虑我们如何计算 何时撞上某一块砖 这样的东西。对每条边分开算。那么比如现在有一条边,我们还是用那个翻折的trick,画一画可以发现如果这条边的中心是$(x,y)$,射线撞到任何一个$(x+am,y+bn)$就撞到了它(两维上都翻折偶数次。可以发现如果是翻折奇数次的话会先经过上边/下边),其中$a,b$是整数。设射线实际上会撞到所有的$k(x_d,y_d)$,于是我们可以解出$a=\frac{kx_d-x}{m},b=\frac{ky_d-y}{n}$,那么我们要求$k+x^\prime\bmod{m}=0,k+y\bmod{n}=0$的最小的$k$。

于是我们对$x_d,y_d$的四种情况分别给所有数解出来一个$k$然后排序(两个是另两个取负),那么每次沿着某个方向找一个后继然后删掉它即可。二分出这个位置然后用并查集找。复杂度$O(n\log v)$。

Wcale nie Nim

看起来非常恐怖。显然A的每一步都会清空一堆。看看样例,我们知道如果$n=1$答案是$2\lceil 1+\lg a_1\rceil+1$。

注意到一对结束之后,B不得不把一步给别的某对堆$x,x$。那么他显然会把这对堆变成$x+1,x-1$。如果$x$是$2$的幂$+1$那就少了一步,此时A必然会跟上来取走$x+1$。如果A去了别的堆,那么那边清空之后B就可以把这边变回$x,x$。

我们将A把一对中大的拿走这个操作称为拿,B把一对中有一个$0$的摊平称为摊,B把平的一对搞的不同称为炸。如果只有拿和摊,答案就是$\lg$的和之类的。那么只有炸可能省出步数,并且最多省下一步。观察二进制,如果一对是$a,a+1$则不会被炸,如果是$a,a$且$a$的二进制表示全$1$,那么一轮炸-拿-摊可以把$a$的长度减少$1$,如此一直进行$a$的长度次才能减少一步,一旦中断就不可能减少一步了。于是A可以上来先全搞成全$1$的形状,然后两个人每次都会选择最长的那个操作,B是因为最长的最不容易有用,A是因为要逼B往短的上走。A一旦先手操作一堆就会操作干净,因为它上面不可能再省下步数了,而B会让这一堆长度减少$1$。最后每一堆长$1$的都能贡献,如果A先手则有一堆不行。胡乱模拟即可。

Stage III

Równoważne programy

感觉比较厉害啊。注意到操作可逆,所以我们可以进行一个排序,把它们都换的字典序尽可能小。那么从左往右枚举一个位置,我们希望换过来一个尽可能小的,枚举它的颜色,找到右边第一个这样的,然后判断能不能换过来,这当且仅当它能和这一段中每个数换。考虑直接维护每个颜色能不能换过来,问题是单点清空,求前缀bitset的or的某一位,线段树就是$O(\frac{nk\log n}{w})$。

但是std不是这个复杂度啊。std做法大概是枚举一个颜色,如果相邻两次出现是$i,j$,那么记录$[i,j]$中不能和这个颜色换的数的个数,然后对上去判断是否相同。证明考虑找一个好一点的翻译器。我好像考虑到了类似的hash做法。

Posłaniec

还是比较简单的吧!先$n^4$跑个路径数,然后我们要减去多次经过起点/终点的,那就枚举经过起点/终点的环来容斥,大概是$\sum\limits_i\sum\limits_j c(u,u,i)c(v,v,j)c(u,v,d-i-j)$这样的。枚举两个点预处理$c(u,u,…),c(v,v,…)$的卷积即可,复杂度$O(n^3d+n^2d^2+qd)$。

Pracowity Jaś

1e9+7秒大约是31.7年。

这就需要我们看看prev_permutation到底干了啥事了。看起来我们应该找到最短的后缀满足它不是递增的,这个位置就是第一个下降的位置。设它是$k,a$,其中$k$是数,$a$是递增序列,$k>a_1$,那么我们要做的就是把$a$中$k$的前驱换到$k$这里,剩下的数从大到小排序。于是只有$a$的长度和$k$在$a$中的排名是重要的。可以算出来如果$a$中比$k$小的有$l$个,大的有$r$个,那么答案是$l+1+\frac{(2l+r+1)r}{2}+\frac{l(l-1)}{2}=\frac{(l+r)^2+l+r+1}{2}$。

于是说只有$a$的长度是重要的,这个排名也是不重要的了。那么就是要求所有字典序比某个排列小的排列,极长递增后缀长度的和和平方和。还是枚举前面长度相同的段,剩下的部分就是一个没有字典序限制的问题。设$f(n)$表示长$n$的排列的答案,考虑枚举这个后缀的长度$k$,那么首先有$\binom{n}{k}$种方案选出这个后缀,前面随便排就是$(n-k)!$,但是这个会把一个实际上极长后缀长$d$的排列在$k=1,…,d$处都算一次,所以还要差分一下。式子看起来像是$f(n)=\sum\limits_{k=1}^n\binom{n}{k}(n-k)!k^e=n!\sum\limits_{k=1}^n\frac{k^e}{k!}$,后面跟$n$无关了,前缀和即可。

Żywopłot

对偶图mst。

Klubowicze

看起来很牛逼,当场无人通过。收录于 格雷码相关问题。

Niebanalne podróże

这个题看起来大概区分出了波兰国家队。

也就是求是不是所有简单环的长度都相等。这里我们既不能求出最大环,又不能求出最小环。

那么我们先跑一个dfs树,dfs树上有很多环,并且这是无向图所以dfs树居然只有返祖边。

如果所有的非树边覆盖的链都不交,那就比较简单了。

如果有的非树边覆盖的链交了,考虑设所有非树边覆盖的链的长度都是$l$,那么一个环合法当且仅当长度是$l+1$。设两条非树边端点分别从上到下是$(u_1,v_1),(u_2,v_2)$,那么设$d_u=\mathrm{dis}(u_1,u_2)$,$d_v$同理,交的部分就应该是$\mathrm{lca}(v_1,v_2)$上面的一段,我们可以得到一个长$d_u+d_v+2$的环,于是应该有$d_u+d_v=l-1$。在$\mathrm{lca}(v_1,v_2)$处统计,以它为根我们知道$d_u=\vert\mathrm{dep}(v_1)-\mathrm{dep}(v_2)\vert,d_v=\mathrm{dep}(v_1)+\mathrm{dep}(v_2)$,也就是说$d_u+d_v=2\max(\mathrm{dep}(v_1),\mathrm{dep}(v_2))$,于是实际上只要求,要么只有不超过一个子树中有$v$,要么(不存在$2\mathrm{dep}(v)>l-1$的$v$,且有$\mathrm{dep}(v)<l-1$的$v$的子树不超过一个)。当然这里$\mathrm{dep}\geq l$的点要删掉。

考虑经过至少三条非树边的情况。如果它要有贡献,考虑我们走的前两条非树边,它们一定满足到它们$v$的lca的距离一个$=\frac{l-1}{2}$另一个$<\frac{l-1}{2}$,这俩分别称为低的和高的吧,不能两个都$=$是因为这样就直接接起来了不能再走。那么接下来我们要转到第三条非树边上,这条边如果更低那么它和这俩中任何一个都能凑出不合法来,于是它必须更高,于是它的$v$不能比前两条边的lca低,如果低了那和高的就凑起来了。它又不能比两条边的$u$都高,否则走不过去。如果它的$v$比低$u$低那么它就和低边凑成了不合法,如果介于两$u$之间,那么考虑它的$v$和高$v$的lca,高边在这里的深度必然是$>\frac{l-1}{2}$的,于是又凑成了不合法。所以如果有环经过至少三条非树边,必然不合法。

到这里我们知道对于第一问直接长剖一下存哪些深度有$v$,并维护一个指向$<l$的$\max$的指针即可,移动它的总复杂度是线性。考虑怎么数数,合并的时候距离$=\frac{l-1}{2}$的选两个,如果有$<\frac{l-1}{2}$的再拿它配$=\frac{l-1}{2}$的,这就是所有方案了。复杂度线性。

Parada

也就是在树上求最大毛毛虫,中心链上的边没有贡献。dp,在lca处统计即可。

XXIV(2016~2017)

Stage 1

Flappy Bird

猜测保持尽可能低就可以得到答案,因为如果一个位置不是尽可能低,我们让它降低要么是把升高延后了,要么是真的减少了一次升高。

黑白染色,那么每个柱子的下侧限制就是$y-x>a_i-x_i(x\leq x_i)$,而由于我们贴下侧走,一旦撞了上侧就没救。扫出一个单调栈,然后在上面和上侧的限制上双指针即可。

题解做法简单一些。考虑答案由我们最后到的点中最低的那个的坐标确定,直接扫过去,维护我们可以到的点的最小和最大纵坐标,然后就结束了。

Podzielność

考虑$b-1$的倍数有啥性质。经典的,$b^k-1=(b-1)(b^{k-1}+…+1)$,也就是说$b^k\bmod{b-1}=1$,也就是说$b-1$的倍数就是各位之和为$b-1$的倍数的数。

首先考虑我们怎么选最多个。想了想发现了$a_i\geq 1$这个牛逼条件,于是我们直接扔掉一个和总和膜$b-1$相等的,如果这个是$0$则可以不扔。查询的时候在前缀和上二分一下即可。

Reprezentacje różnicowe

看起来牛逼题。然后仔细一看发现这个序列好像是为了这个性质构造的,那个$r$就比较直白了,那么考虑$a$很大的时候$\times 2$就没啥贡献了,只有$+r$有贡献,而这个每次会让$r$增加$1$,也就是说我们统计一个足够长的值域范围内覆盖了$x$以内的多少数,设有$c$个,如果覆盖了$x$就结束了,否则答案就是再往后$x-c$对。复杂度$O(n\log\log v+\log^3 v)$。

Sabotaż

第一个叛徒肯定是叶子,因为这里算的时候不包括他自己,而叶子的子树不会更大。然后他肯定是一级一级地往上推。对每个叶子求出向上占领各级所需的比例的$\max$,取个$\min$即可。

Turysta

求一下所有的scc,每个scc跑一个哈密顿回路,然后跟下一个scc串起来即可。

Stage 2

Zawody sportowe

如果一个连通块边数超过点数,那就没救。否则是基环树森林,环上如果环长$\geq 2$有两种选择,树上只有一种,toposort即可。

Strajki

贺个动态图连通性先。但是这里是删点,这就很不好。考虑维护存在的边数,根号分治,对于每个点我们维护周围度数比它小的点有多少个还存在,这样如果一个点的度数是$k$,全图度数比它大的点个数就不超过$\frac{n}{k}$,那么改它的复杂度就是$O(\min(k,\frac{n}{k}))$,总复杂度$O(n\sqrt{n})$。

考虑能不能更快一点,毕竟这里是树。好像儿子在bfs序上是一个区间,所以BiT就好了。比较智障!

Suma cyfr

dp。设$dp(i,j,k)$表示$i$位,膜$m$为$j$,和为$k$的数的个数,然后从高到低确定每一位即可。

Kontenery

根号分治。

Zamek

先把不能走的找出来。也就是一个单点修改矩形求和。

然后建出图来。枚举一个横坐标,按纵坐标排序,这里矩形不交就很好,爆力双指针即可。

然后bfs。

Stage 3

Dostawca pizzy

猜个凸先。

考虑个dp先,设$dp(u,i,j)$表示$u$子树走$i+j$次,其中$i$次回到根,$j$次没有的答案,转移就爆力卷,复杂度$n^3,n^4$区别可能不大。

但是这东西好像不好直接优化!需要一个牛逼结论。考虑我们钦点所有终点,那么如果一条边子树中有$k$个终点,它经过至少$k$次,如果$k=0$则是两次。猜测总有一种方法达到这个下界。问题仅在于子树中有终点的边是否必然可以不被一条终点在子树外的路径经过。注意到进来又出去就形成环,而已经有一条路径进来了,那么把这个环接到那上面即可,也就是说这个下界确实是恰到好处的。

那么我们就只需要钦点终点了。设$dp(u,i)$表示$u$子树有$i$个终点,计算父边边权$w$的贡献的答案,那么$dp(u,0)=2s(u),dp(u,i)=iw+\min\limits_{\sum j=i}\sum dp(v,j)$,$s$是子树和父边的边权和。复杂度$O(nk)$。这大致等价于在上面那个爆力中断言如果$j>0$则$i=0$,否则$i=1$。

那么接下来归纳一下证明凸性。考虑叶子看起来是凸的,$dp(u,…)$是儿子们的$\min,+$卷积塞上一个$dp(u,0)=2s(u)$,可以注意到的是$dp(u,0)>\sum dp(v,0)$,所以它确实是凸的。然后可以wqs二分或者静态链分治合并凸函数。

Midas

好像它说的是树啊。那么我们求一个lca就好了啊?

如果不是树,递推,主席树多树二分。复杂度$O(m\log n)$。

Oceny

英文题面有误,应为后面的不能比前面的小。

考虑把这俩画到平面上,那么一个点左上和右下方的必须和它相同,而连通块之间必然可以不同,我们就是要求有多少连通块。

这个问题好像比较经典!因为这是排列,考虑问题相当于画尽可能多的十字使得每个十字只有左下和右上有点,这又相当于查询有多少个间隔满足左边的$\max$比右边的$\min$小,那么也就是查询有多少个前缀$i$满足$\max=i$。如果$i$出现在$j$,那么相当于$[j,i-1]$都不可能成为答案,如果一个位置没有被这样覆盖则显然是答案,线段树维护$0$的个数即可。

Zapiekanki

无人通过!恐怖极了兄弟。

把题面中的$k$称为$n$。

这是一个有容量限制的摆渡车。考虑相当于在数轴上放若干个点,相邻两个距离$\geq d$,然后每个人往后匹配一个点,一个点最多匹配$z$个人。经典的,首先每个点要么和一个人重合,要么在上一个点后恰好$d$的位置。dp,设$dp(i,j,k)$表示从第$i$个人开始连续放了$j$个点,还有$k$个人没匹配的答案,复杂度$O(n^3)$。

注意到如果有至少$z$个人,我们必然尽可能早地放一个点,这样就是$O(n^2z)$了。于是希望把$i,j$砍到$O(\frac{n^2}{z})$的级别,但是不太行啊,毕竟摆渡车里面是$z=n$的。

换个想法,首先这里$j>0$时的转移是唯一的,所以我们直接把这一维扔掉,改为转移的时候枚举连续选多少次。至于选多少次呢,当然是选到满。那么假设我们现在要处理$dp(i,…)$的转移,当我们遇到一个$x_i+td$的时候我们选择$x_i+(t-1)d$这个点,这个操作的效果大概就是$>z$的部分加$z(x_i+(t-1)d)$并平移$-z$,$\leq 0$的部分加$j(x_i+(t-1)d)$并拍成$0$,这里后者有均摊。然后还要把下一段的操作重做一遍。可以发现的是主要问题是我们需要做这么多平移,感觉完全没法做啊!

考虑现在是不是容易看出什么牛逼性质了,注意到如果一个状态想要坚持不被拍到$0$,它只能坚持最多$\frac{n}{z}$轮,而刚才还说如果有至少$z$人在等,我们必然继续放一个点,所以$\geq z$的这部分是不用转移的。所以复杂度又$n^2$了。这么说一开始应该也可以看出来的啊,还是眼力不好!

Kucharz

看起来又是有趣卡空间题。但是这个题不够有趣,注意到如果我们用操作$3$,必然是希望早用,于是有能量我们就会用,于是枚举一开始连用多少次,能量就没有意义了,只需要开一个长1e6的$dp$数组。

Rozdroża parzystości

classic。考虑我们就是求一个字典序$k$小的方案,先把所有东西插入线性基,那么一棵生成树将会调整一切。如果我们改变一条非树边的状态,对应树上的链跟着改变即可,也就是说我们首先随便得到一个解,然后在环空间中求一个和它xor的第$k$小。

为了随便得到一个解,每两次对目标的修改,把它们在树上的链取反。

为了在环空间中求和它xor的第$k$小,如果生成树上的边是编号最小的那些我们就赢了,否则我们需要消出一个对角基来,但是这个巨大矩阵上大概不是很好操作。考虑能不能通过选择一棵特殊的生成树解决这个问题,我们选择字典序最小的生成树,那么对于每个基础环,上面最高的位一定是那条非树边贡献的,否则把它替入就得到字典序更小的一颗生成树。于是我们在此上贪心即可。$k$的改变只可能影响最低的$\log v$个基础环,爆力即可。求字典序最小的生成树使用kru。

XXV(2017~2018)

Stage 1

Pionek

考虑必然是存在一条过原点的直线,它的一侧我们都选,另一侧我们都不选。扫描线扫一扫即可。

Plan metra

容易想到找到$1$到$n$这条链,一个点$u$到链的距离就是$\frac{1}{2}(d(1,u)+d(n,u)-d(1,n))$,而它应该挂在链上$d(1,u)-d(n,u)$和它相同的那个点上,于是我们找到这条链之后就容易挂成一个毛毛虫了。那么考虑一个$d(1,n)$合法,当且仅当每个点到链的距离都是整数,这可以简单地用奇偶性限制住,并且每个点都和某个在链上的点具有相同的$d(1,u)-d(n,u)$。显然对于每个$d(1,u)-d(n,u)$等价类,其中$d(1,u)$最小的那个点是在链上的,用它们求出一个$d(1,n)$,如果有不同的那就无解了,然后直接如上构造即可。

或者简单一点,$d(1,n)$就是最小的$d(1,u)+d(u,n)$。

但是这里有问题,如果没有一个点在链上,或者说$1,n$是相邻的,我们就死啦,所以需要check一下$d(1,n)=1$的情况。

Powódź

感觉比较有趣啊。显然还是要扫值域,考虑每个高度是若干个连通块,每个连通块周围都是高度不低于它的墙。考虑这个连通块的结构,在序列上它是卡笛尔树,那么在矩阵上,考虑从大到小扫这是一个合并的过程,于是它还是一棵树。那么在这棵树上dp,也就是求一个 每个点到根路径上选恰好一个点,然后每个点有一个权值(在某两面墙的高度之间可以随意选),所有方案中权值积的和。dp即可。

Prawnicy

模拟。

Różnorodność

考虑枚举一条横线,那么我们在这条横线上还是可以算每个颜色上一次在哪个竖条中出现然后数点。那么横线扫过去的时候会有插入删除,用set维护每个颜色即可,复杂度$O(n^2\log n)$。

Stage 2

Przelewy

剥叶子。

Drogi rowerowe

看起来这个比较有趣啊。缩个scc先,那么我们考虑如果$u$不能到$v$,则$v$有不超过一种方案到$u$是啥意思。我不理解,但是发现不用理解,因为在这种图上直接dp就是对的。

Konduktor

第一问把包含其它区间的区间去掉,然后直接贪心找到左端点最左的还没有包含一个的,在它的右端点放一个。

那么考虑dp,设$dp(i,j)$表示放了$j$个,最后一个在第$i$段的方案数,这里按照哪些区间包含这个点划分成$O(n)$段。注意到如果贪心得到的最优解在前$i$段放了$j$个,某个方案在前$i$段放了$j+2$个,并且在第$i$段放了一个,那就救不了啦。于是每个位置只有两个$j$有用。转移的时候找到完全在$i$左边的区间中左端点最右的,然后从它上面转移过来,前缀和即可。复杂度是线性的。

Przekaźniki telekomunikacyjne

简单ds题。维护区间和和一个等差数列标记。

Tomik poezji

先给所有$a_i$加上$1$。问题就是把它们分成尽可能少的组,使得对于每一组存在一种排列方式使得所有真前缀的和膜$s$都不为$-1$,且除最后一组外每一组总和为$-1$。考虑什么样的组是存在一种排列方式使得所有真前缀的和膜$s$都不为$-1$的。但是感觉不好考虑。

不过还是可以的嘛,考虑如果我们有至少两种长度,那么其中一种必然可以使得和膜$s$不是$-1$。这时候容易猜一个按出现次数贪心的做法,但是这个看起来并不好证呢。

让我们看看我校伟大的cmo Ag爷怎么说。

  • 如果某一时刻出现次数最多的数不止一个了,那么答案必然是$0$,因为如果有至少两个数$a,b$,我们现在不能选$a$,那么选完$b$必然可以立刻选$a$。

  • 否则,最后剩下的数必然是一开始就出现次数最多的数,设它是$a$。

    • 如果$a\not\perp s$,它只会剩下最多一个,否则考虑在这一时刻之前我们选了某个$b$,好像在$a\mid b$的时候会出问题。考虑我们找到最后的极长段,满足如果其中某个位置的和是$t$,有$a\mid s-1-t$,那么在这一段前一位我们选的数必然不是$a$的倍数,因此它当时只剩一个了,那么除非所有数都只剩下了一个,否则我们是不会选它的。于是答案还是$0$。

    • 如果$a\perp s$,我们把所有数除$a$,那么相当于我们在数轴上不停往右走$1$到$\frac{s-1}{a}-1$,然后走某个别的数,这样的。考虑我们走过的总长度,总是要经过那么多次$\frac{s-1}{a}$,用$a$之外的每个数只能跨过不超过一个,因此总是跨过一个必然是最优的。

Stage 3

Dwa pionki

还是枚举最后两个点连线的垂线,那么沿着这条垂线方向尽可能选即可。

Trzy wieże 2

好像其实是Trzy wieże 1的一部分。在做Trzy wieże 1的不久之后我在tricks里面说这类问题是经典的维护特例。

Liczby kompletne

见鬼捏。考虑首先枚举位数,那么我们把位数分解,然后dp,设$dp(i,j)$表示,假设我们当前这个数是$x$,那么$\lfloor\frac{n}{x}\rfloor=i,d(x)=j$的方案数,这里$n$是$x$的范围。但是这个好像不是很有前途,因为转移的时候我们总要枚举素数幂啊。不过我们知道这个可以做$O(n^{\frac{3}{4}+o(1)})$,鉴于基本和组的平方根之和是$\frac{3}{4}$级别。

看起来可能需要点性质。首先我们知道因数个数是$\log_{10}$的数,素因数个数就不超过$\lg\log_{10}$了。大力讨论,先考虑九位数怎么做,$9=3\times 3$,也就是说它有两个素因数,每个都是两次,或者有一个素因数是八次,两种情况都是简单的,精细实现可以做到$O(\sqrt{n})-O(n^\frac{1}{4})$。大概需要注意直接算前一个会算重。

七位数及以下线筛。只要考虑一下八位数就赢啦。

那么八位数可能有三个一次的素因数,一个三次和一个一次,或者一个七次。最后一个是简单的,中间那个可能要素数计数,前面的感觉更不好做啊。

妈的,能不能线筛直冲1e8啊?当然可以,分段打表即可。

Ogrodzenie

dp。枚举开头$s$,设$dp(i,j)$表示前两个选了$i\rightarrow j$的答案,转移可以转移到$dp(j,k)$,其中$k$是一个前缀,预处理出这个前缀然后打个标记即可。问题是怎么做三角形数点,这个是经典的。

Turniej trójinformatyczny

感觉比较有实力。

首先这是一个竞赛图,如果$a$在任意两项上不能胜过$b$,那么说明$b$必然在某两项上胜过$a$。于是问题是找到所有的scc以及求scc之间的拓扑序。

考虑kosaraju,问题是需要找到一个点可达且还没遍历过的任意一个点,树套树,复杂度$O(n\log^2 n)$。

但是这有点极端了。考虑能不能稍微的快一点,发现这里只需要求一个前缀$\min$,复杂度$O(n\log n)$。

让我们复习一下kosaraju。在正图上求离开序,在反图上按离开序的倒序dfs就按正图上的拓扑序找到了所有scc。

Dwa długie lizaki

把每个区间的两维画到平面上,那么每个区间就是一个矩形,要求交中$x+y$最大的点,扫描线线段树即可。

Taksówki

空跌之言可谓切綮。我们只需要满足每相邻两个确定的限制,因为它对这相邻两个是充要的。

Wielomian

法法。

XXVI(2018~2019)

消失之年。你在洛谷上找到的poi2018是xxv,2019是xxvii,xxvi可能是poinan吧。

Stage 1

Klubowicze 2

也就是把一个环分成两段满足两边的or相同。$n,m$看反就比较乐。一开始看成了分成两个子集,这东西大概不可做啊。这个就比较简单,我们枚举一个分界点,找到左右最短的使得or等于全局or的地方,然后这俩中间都可以当另一个分段点。双指针,使用两个栈维护or即可。

Robocik

小波特罗比。

每轮就是一个平移,每个膜$n$等价类是一个等差数列,看看它有没有经过目标即可。

Para naszyjników

我们知道所有长$k$区间的奇偶性都相同,当且仅当相距$k$的两个数总是相同。那么问题变成判断平移$k$之后是否和自己相同,hash一下就好了,或者直接kmp求出所有border。

看起来官方题解比较厉害。考虑如果两个串长度相同怎么做,如果它们奇偶性相同就赢了,否则如果四端不都相同那么删一次答案是$n-1$,否则我们找到离任何一端最近的和四端都不相同的,然后把它那一侧扔掉。

如果两个串长度不同,我们枚举长串的一个区间,问题就是求出左/右第一个0/1,很容易线性。

Podciągi

感觉官方题解还是比较厉害。设本质不同子序列数是$f$。考虑我们每次选择一些没出现过的字符,在左边放一个$a$右边放一个$b$,那么本质不同子序列数会乘上$f(a)f(b)$,然后减去$f(a)f(b)-f(ab)$。通过爆搜,找到所有长$\leq 7$的$a,b$就可以覆盖1e18。

Niedbałość

贪贪你的。维护左右目前出现过的字符,如果有重合那就选过去,然后把跨过的一段删掉。

Stage 2

Rozliczenia

BiT。

Gwiazdy

如果可以任选起点,那么所有东西都可以搞出来啦!

猜测就是几乎所有东西都可以搞出来。但是显然不总是这样,比如如果$s=1$,第一步必须往右。注意到首先总可以让只有第一步可能不能搞出来,具体一点就是先扔掉$s$并不考虑第一步,倒着考虑,不妨设最后一步是往右,如果是连续长$k$的往右,那就从$n-k$开始走到$n$,然后如果是长$k^\prime$的往左,就走到$k^\prime$然后一直走到$1$。最后用第一步走到$s$。这样只有第一步可能不能搞出来。

感觉这个构造已经很厉害了!考虑一个更猛的,注意到如果在$i$,我们就没法在开头连续往左$i$步,但是开头的连续往左结束之后就相当于任选起点了,所以其实只对开头连续相同段的长度有限制。这就赢了。

Kolacje

每种和查询一起拿出来建个虚树,然后变成链$\min$了,可以并查集做到$O(n\alpha(n))$。

我好像不是很会写虚树。

Przesunięcie cykliczne

考虑第二个subtask怎么做。分块,我们每次走过比如$K=50$,那么走$t$步时转了一圈回到一开始的地方后面一点的话,也就是说一开始是$a_0$,$a_{t-1}<a_0$,且 $a_t>a_0$或$a_t<a_{t-1}$,那么序列长度就在$((t-1)K,tK)$中,爆力尝试$K$种即可。

或者直接随机走期望$\Theta(\sqrt{2n})$步,然后就会得到两个相同的数,此时走的总长就是一个$n$的倍数,给这个数分解素因数每次尝试删掉一个素因数发生什么,这是$\sqrt{2n}+\log n$。

那么考虑怎么二分之类的啊。

感觉比较厉害。考虑我们先让前$i$次跳$2^i$,$i$从$0$开始,也就是说我们每次跳$1,1,2,4,8,16,…$,直到找到第一次 这个数比上个数小 的时刻$t_1$,这就越过了$n$。然后再跳,找到第一个比起点大或者比上个数小的时刻$t_2$,这就走完了一圈。那么我们知道$n$就在$(2^{t_1-1}+2^{t_2-1},2^{t_1}+2^{t_2})$中。

现在在其中二分一个答案$d$,因为这个区间是$(k,2k)$这样的,我们知道$\frac{n}{2}<d<2n$。但是现在我们不知道我们在什么位置捏。做法比较的强力,我们假设$d$是偶数,如果不是偶数就微调一下。从任意一个点$a$出发跳两次$\frac{d}{2}$,分别到达$b,c$。如果$d=n$,那么$a=c$。使用geogebra观察一下,发现$d<n$的时候三个点的顺序总是$a,b,c$的循环同构,$>n$的时候总是$c,b,a$的循环同构,或者你可以把它看成$d$的一次函数然后想象一下。这就赢了。我不是很理解这东西是不是有什么深刻的结构啊。

Osiedla

经典的,每个e-dcc可以直接任选一棵dfs树,那么每个点子树中都有返祖边,dfs树向下而返祖边向上即可。e-dcc之间没救。

Stage 3

Metro

classic。二分答案,然后贪心。

看起来有牛逼做法。直接以center为根,长剖选前k长链。

Remont

为啥这么多一眼看上去没有多项式复杂度爆力的题。问题相当于每个间隔选或者不选,相邻两个间隔不能都不选,相同颜色的间隔不能都选。

可以说是一眼网络流!但是很遗憾我并不会。考虑拟阵交,也不行。本质上来说,颜色限制是独立,序列限制是覆盖。

考虑线性规划。但是我好像证明了它不是全幺模的。

考虑2-sat。这会可以了,但是一个颜色出现很多次的话,需要连很多边。不过前后缀和优化建图一下就好了。我想了一年才想到,感觉比较智障!

Wyścigi

考虑如果只有一次查询,显然我们会倒着分配这个得分,也就是排名$i$的获得$i$分,这里排名定义为更大的数的个数。那么就是要这样求全局最大值个数。

发现排名压根不会变,所以线段树维护即可。deepl给我把操作2翻译成$\geq x$的$-y$了。

Zjazd obieżyświatów

感觉比较厉害。

先给答案一个上界。考虑枚举终点,因为只要上界,我们可以要求终点在一个环上,毕竟每个点都可以在$O(n)$步内走到一个环上。因为大家都会到终点,我们随便找一个终点所在的环,膜它的长度从终点出发跑同余最短路。这证明了答案不超过$n^2$。

于是考虑如果有点不在环上,枚举答案,我们要$01$矩乘$n^2$轮,每次乘法是$\frac{n^2}{w}$,要乘$n$次,然后全部and起来。复杂度$O(\frac{n^5}{w})$。

发现我比较智障。发现这玩意可以二分,因为所有人在$t$时刻相遇之后,只要一起走,就能在$t+1$时刻继续相遇。所以倍增即可,复杂度$O(\frac{n^3\log n}{w})$。

Długie podróże

切了这题的都没进国家队/cf

考虑既然要经过$\frac{n}{10}$条边,就是$\frac{n}{10}+1$个点,我们随机一个点有$\frac{1}{10}$的概率随到这条路径上,随到了的话从它出发bfs一下就赢了,那么算一下,假设有$50$组数据,那么我们需要在1e7次询问中幸存,比如要$\frac{1}{1000}$的错误率吧,每组的错误率就要在$10^{-10}$。我们每随一个的错误率是$\frac{9}{10}$,那么看起来随$\log_\frac{9}{10}10^{-10}\approx 218$个点就好啦。

Gra w dzielniki

很容易写一个dp,也就是设$dp(i)$表示现在在$i$的期望时间,转移枚举得到了啥,只有它是不是因数有关系,复杂度$O(n\log n)$。

猜测方差很小,因为这东西看着就很像二项分布,所以直接做就好啦。

Ornitolog

例行卡空间题吗。

注意到$a,b$很小,类似于约瑟夫问题的做法,我们每次都能砍掉$\frac{n}{a}$个,也就是把它变成了$\frac{a-1}{a}$,算一下算量大概是2e5啊。

具体一点,我们每次删的是一侧的一个等差数列,求出每次删了多少个,找到答案在答案被删时的位置之后,倒着扫并维护它的位置。如果一个位置在删掉了各$ai+b$之前是$x$,那么它就会变成$x-\lfloor\frac{x-b}{a}\rfloor$,如果$a\mid x-b$它就会被删掉。所以如果它删掉之后是$y$,那么$y=x-\lfloor\frac{x-b}{a}\rfloor=\lfloor\frac{(a-1)x+b}{a}\rfloor$,我们爆力拆解下取整就是$\frac{(a-1)x+b}{a}-1<y\leq\frac{(a-1)x+b}{a}$,解得$\frac{ay-b}{a-1}\leq x<\frac{a(y+1)-b}{a-1}$。两侧分别给出$x=\lceil\frac{ay-b}{a-1}\rceil,\lfloor\frac{a(y+1)-b-1}{a-1}\rfloor=\lfloor\frac{ay-b}{a-1}\rfloor+1$。看起来只有$a-1\mid ay-b$时它俩不相等,此时必然有$b=y$,那么看起来我们应该取后者。

XXVII(2019~2020)

可以称为近代题了。

Stage 1

Pomniejszenie

必然是把高若干位改相等,然后如果接下来$a$本身就小就不用管了,否则需要留一手以改小。有趣的是如果正好撞到$0$上就没救了,此时我们往前找到第一个非$0$的,在这里改小,然后后面全改成$9$。

Pisarze

¿

有空练个ai。

Przedszkole

草,这不是挑战色数吗。

看一眼范围,原来是分成三部分。

$n\leq 15$。子集卷积$k$次。$k$可能很大,所以$\ln-\exp$,复杂度$O(2^nn^2)$。或者$O(2^nn^3)$,设$dp(i,S)$表示恰好用了$i$种颜色,填满了$S$的方案数,子集卷积,最后选出这些颜色即可。考虑有没有好写的$O(3^n)$之类的,好像只能$O(3^nn)$啊。

$m\leq 24$。如果一个点是一度点,它的贡献就是不能选和它的邻接点相同的颜色,也就是给答案乘上$k-1$。如果一个点是二度点,我们把它缩进边里。用和上面一样的dp决策所有度数$\geq 3$的点的颜色,然后每条缩了一些点的边只有端点颜色相同或者不同有贡献,复杂度$O(3^\frac{2m}{3}m)$。

看起来也可以对边容斥。

2-正则图。若干个环。考虑从随便一个点断开然后dp,每个颜色只有和起点相同还是不同有关。或者容斥也是可以的。

Układ scalony

考虑我们可以构造任意长的直径,但是不能构造任意短。最短的就是$n+m-2+[2\mid n,2\mid m]$。

为了构造中间的,考虑转转然后冲进一条对角线。沿着某一个方向走几个之字形,然后现在我们到了某个角,再拐一次就超了,那么从对角那里伸出一条来,中间构造一个最短的即可。

感觉我的强行构造水平还是不行。

Najmniejsza wspólna wielokrotność

首先注意到相邻的两个数总是互素的,也就是说它们的lcm必然是它们的乘积。相邻三个数$a,b,c$,只可能$a,c$都被$2$整除,并且它们除掉一个$2$之后必然互素,也就是说lcm至少是$\frac{abc}{2}$。我们在大约1e6以内枚举所有lcm不超过1e18的区间,并特判两个数的情况即可。

Stage 2

Wakacje Bajtazara

也就是让奇数天的和尽可能大,并且不能两次在奇数天在一个点。那么考虑我们走出来是个什么形态,不妨假设偶数天在白点,我们选择了一串白点和它们的邻域,相邻两个白点的邻域有交。dp,设$dp(u,0/1)$表示$u$子树的一条祖先-后代链,$u$是最高的白点/黑点的答案,这里如果$u$是黑点,$u$要贡献一个负的点权,在儿子中找一个不同颜色的以转移,或者找两个以统计答案。

Drzewo czwórkowe

每个点的边界分成若干段,我们需要大力维护它分成哪些段以及这些段的连通性。超级模拟/cf

有趣的是这里不需要合并,因为两个点的边界相交的话,一个点在这一边必然不能再相交了。直接这么加边即可。

为了统计答案,从高到低模拟。每次相等都会让至少一个点消失掉,所以是线性的。

Wielki Upadek

考虑往右的情况,往左就倒过来做。由于新的骨牌都是矮的,我们必然希望用它们去塞一些间隔。问题就是应该怎么塞。

设第$i$个间隔需要$a_i$个短的,长的是短的的$k$倍。那么如果一个长的能代替$k$个短的,显然是不劣的。考虑让长的优先去代替短的最多的地方,那么我们用什么东西支持插入删除求前$k$大和,平衡树即可。

Marudny Bajtazar

2 classic。

Trudny dylemat przedszkolanina

也就是选两个$\leq n$的数使得因数的并集最大。感觉这个比较厉害。

考虑类似于高合成数的想法,注意到$\gcd$和$\mathrm{lcm}$的各素因数的次数应该都是单减的,对着开搜即可。但是我不会搜啊?

Stage 3

Powtorzenia

也就是对每个出现过的颜色计算最多的连续出现次数$-1$的和。特判两边的段,中间对每个颜色建卡笛尔树然后主席树数点即可。

Szyld

感觉比较带劲。设两个串分别是$a,b$。如果$b$有字符没有在$a$中出现过,那么答案是inf,否则答案必然不是inf。

考虑我们肯定是每一个和上一个的最长真border重叠,因为重叠的少了不会让$b$变得不出现。所以问题就是这么重叠多少次会让$b$出现。在vector上二分找到下一个我们要的字符在哪即可。

Unia Bajtopejska

让人想起那个区间gray code题。

考虑$a=0$咋做。考虑如果还有$b=2^k-1$咋做,考虑分成左右两半,那么两部分之间的边边权都至少是$2^{k-1}$,而内部都$<2^{k-1}$,所以我们必然是内部连起来然后两侧放一个。

于是考虑$a$到$b$之间变化的最高位$k$,两部分之间的边权都至少是$2^k$。从这里断开递归两边。考虑当区间变成trie上的子树的时候剪一下,$[0,2^k)$的答案就是两倍的$[0,2^{k-1})$再加上$2^{k-1}$的一条边。

那么问题是有两个区间$[a,2^k),[0,b]$,要各找一个数使得xor和最小。考虑从高到低贪心,如果$a\leq b$那答案就是$0$,直接结束;如果$b<2^{k-1},a\geq 2^{k-1}$那这一位可以扔掉;否则我们让$k-1$位是$0$并递归下去。复杂度$O(q\log^2 v)$。

注意到除了第一次分治的合并,剩下的时候都有$a=0$或$b=2^k-1$,所以这些都是$O(1)$的,复杂度$O(q\log v)$。

Reprezentanci firmy

一眼模拟费用流。考虑怎么表示这个 一个区间至少有多少人 的限制,先不要上线性规划,让我们想一想。

想了想发现不行捏。线性规划,每个区间限制总和,每个人还要限制$\leq 1$,每行的$1$或者$-1$都是连续的,所以这玩意非常全幺模。对偶,问题变成给每个区间分配一个数$y$,每个人分配一个数$x$,使得对于每个人,包含他的区间的$y$的和减去他的$x$,结果$\leq$他的$c$,每个区间每选$1$可以获得$p$,$x$每选$1$获得$-1$,最大化总贡献。那么这个$x$的效果也就是多了多少减去多少呗。

哦这个对偶是不是和 雪的魔法 或者 zjoi2013 防守战线 差不多啊。

建图也是差不多的。建一排点从左往右连,每两条边对应一个人,这两条分别是容量为$c$费用为$0$的和容量为$\infty$边权为$-1$的边。每个区间从右端点对应边的右端点连到左端点对应边的左端点。跑最大费用循环流。

开始模拟费用流。发现这里会各种退流,完全模拟不了。

继续发现少看了一个条件,原来这是个树啊。dp,设$dp(u,i)$表示$u$子树,上面已经选了$i$的答案,那么子树间完全是互不影响的,可以直接求和,就看$u$选多少。当然猜测$dp$是凸的,为了证明这件事,我们在左边挂一个$s$右边挂一个$t$就变成源汇流啦。那么$u$选多少的贡献就是$f(x)=p_ux$再加上不包含在子树中的部分的那个超过的代价,它们都是上凸的,于是闵和即可。这里需要用平衡树启发式合并维护。

所以是不是一开始就可以直接dp。设$dp(u,i)$表示$u$子树选了$i$个人,满足子树中所有限制的答案。转移也注意到答案是凸的,闵和即可。

Sieć

也就是邻域$\pm 1$,保证没有负数,求链$0$个数。

那么我们考虑设$k=500$是长度限制,怎么$O(n\log n+qk)$之类的。

点分治,找到包含路径上至少一个点的$O(k+\log n)$个分治块,对每一块查询到它这里剩下的长度最大的病毒,然后正着倒着分别扫一遍就可以求出每个点是否被覆盖啦。复杂度$O(n\log n+q(k+\log^2 n))$,或者你也可以根据邻域半径的限制把$\log^2$改成$k$,看起来会更好写。

你的做法对,但是不如静态top tree。考虑没有$k$的限制咋做,感觉上并不好poly log,这里离线分治也似乎并没有优势。还是树分块吧,每块需要开个堆维护前/后缀覆盖的最长长度,复杂度$O(q\sqrt{n\log n})$。砍砍你的,对每一块离线所有的求$\max$,按照经典的做法,每次找到最大值并推平后面所有的查询,这里值域只有根号直接计排,再上个序列线性并查集就线性啦,总复杂度$O(q\sqrt{n})$。

Tunele czasoprzestrzenne

线段树分治,但是这里最短路变化量很大。是不是猜测它并不大就好了啊(

考虑一些别的能判负环的东西。真的存在这样的东西吗。

所以还是猜测我们需要的松弛量并不大吧。尝试分析但是并没有分析出啥。可以知道的是,必须要建虚点连所有点,并且猜测时间分治比直接删边快。

Bajholmska Firma Transportowa

从大到小扫,每次合并两个连通块。合并的时候会发生什么呢,感觉不是很好办啊!

考虑改成外层点分治,那么每条到分治中心的路径只有是否经过关键边和路径的$\min$有用,线性地卷卷然后给答案打个后缀加标记即可。复杂度$O(n\log n)$。

Kompresja drzew binarnych

从小到大排。但是为啥对呢。发现它确实不对,比如2 4444 4444 6666666666666666,从小到大我们得到4,但是把两个4444放在一起我们得到3。

考虑我们每次钦点出答案中的一个点。dp,设$dp(i,j,k)$表示考虑到$i-1,i$,$i-1$还剩$j$个,$i$还剩$k$个的答案。转移枚举一个点,把$d$看成$\frac{1}{2^d}$,它要满足和是某个$\frac{1}{2^k}$。复杂度也许是$O(n^5)$,这不重要。

考虑两个$i$可以代替一个$i-1$,所以我们应该尽可能多用$i-1$,也就是说把$i-1$打一包,然后尝试去补$i$。$i-1$自己会填满trie的若干子树,$i$的效果就是给它进位,我们需要决策有多少拿去给$i-1$进位啦,有多少拿去跟$i+1$配。这就可以线性的状态数了,设$dp(i,j)$表示$i$还剩$j$个的答案,转移枚举$i+1$用了$2k$个,就产生$\mathrm{popcnt}(j+k)$的贡献。注意到$\mathrm{popcnt}$只有$\log$种,相同的$\mathrm{popcnt}$下多用$i+1$必然不比把$i+1$堆起来留给$i+2$去配对优,因为你把低位都消灭了还往低位放就是直接让$i+1$在贡献嘛。所以有用的决策也只有$\log$种,复杂度$O(n\log n)$。

Skarbiec

显然下界是$\lceil\lg n\rceil$,而直接对每位问这一位是$1$的那些就达到了这个下界。

Bieg na orientację

如果只有一次查询。考虑其Y-center,枚举Y-center,这三个点必须来自不同的子树,或者某一个是Y-center自己。贪心选择最长的子树即可。换根dp得到子树外的信息,或者考虑以center为根也是可以的。

现在有多次查询,这就是一个三维偏序捏。注意到我们只求有没有,并且每维都是1-side的,我们把一维改成求$\max$,就一个$\log$啦。

Miasta partnerskie

看起来是稳定婚姻类似物。但是完全不是,我们直接给每个点找一个最大xor和并连边,那么能且只能选这些边,dinic即可。

Przekaźniki telekomunikacyjne 2

考虑我们枚举那个$\max$在$x$还是$y$上取得,画一画这告诉我们要斜着扫,然后就线段树维护即可。复杂度$O(n\log n)$,但是相当于要扫四遍所以比较的慢。

XXVIII(2020~2021)

我做了大部分poi,但我保留了一部分。我觉得保留一部分,才知道你马上要联合省选了。

cnoi各省

ahoi

2022

A. 排列

这个就是各环长的$\mathrm{lcm}$嘛。然后交换的效果是把两个环串起来,枚举两个环长,不同的环长只有根号种,然后算算方案数即可。

B. 钥匙

感觉一下。考虑每种钥匙不超过一把怎么做,如果经过一把钥匙又经过一个宝箱,并且钥匙到宝箱的路径上没有别的宝箱,那么这个宝箱就有贡献,这就是两个子树或者子树和子树补的笛卡尔积。如果有很多把呢,枚举经过的第一把钥匙,从它出发在虚树上爆力dfs求出每个点作为经过的最后一个点的结果。为了保证它确实是第一把钥匙,笛卡尔积的一侧是所有点减去以它为根其它钥匙的子树。复杂度$O(n\log n)$。

有趣的是其实不需要这么做,我们从一个钥匙出发在虚树上dfs,走到宝箱就停下,把这一对贡献给此时这条链两端的笛卡尔积。那么看一下发现贡献不可能多也不可能少。

C. 山河重整

收录于 数数从入门到直僵僵地镶嵌在门框里。

D. 回忆

也就是给若干对祖先-后代,选尽可能少的链使得每一对都包含在至少一条链中。

这种题一看就不是很阳间啊。感觉树肯定还是很有性质的。考虑序列怎么做,直接全选!考虑网络流,但是不太好办。线性规划谢谢喵。直接设出每条链选多少次,那么看看这玩意是不是全幺模,发现它不是全幺模,那就离谱啦!

感觉还是比较厉害。既然啥都不行,那么我们嗯贪心吧,自底向上做,首先两边的链可以拼起来,没有拼起来的链可以往上延伸。看起来选链的问题,子树中总是只有已经拼起来的和还没有拼起来的链。

如果这一个点有一个到祖先的限制,我们首先考虑把经过这个点且还没拼起来的往上延伸。如果有多条还没拼起来的,那么我们延伸已经需要到达的高度最高的,因为总有一个要到达那个高度,那么维护按需要到达的高度最大的,在深度上打个标记即可。然后考虑是加一条还是把已经拼起来的破开,显然没再有别的决策了,看起来破开已经拼起来的可以让一条有再拼的机会,而加一条没有这个效果,答案都增加了$1$,所以我们把已经拼起来的破开。

接下来考虑怎么拼。有了这个反悔就比较简单了,我们维护这个点已经拼了多少条,现在加入一棵子树,如果前面还有没拼的就跟它拼一拼,否则,我们可以破开前面的两个拼这棵子树的两个。复杂度线性。

bjoi

2017

D1

A. 机动训练

平方的组合意义是选两个的方案数。于是设$dp(i,j)$表示分别结束于$i,j$并且前面也完全相同的路径对数,复杂度$O(n^4)$。

B. 树的难题

点分治先,每次合并最小的两棵子树,那么合并的时候也就是枚举一条链,枚举一个点,然后查长度在某个区间的颜色相同和不同的的最大值。对所有颜色开一个单调队列维护前两大,再对每个颜色开一个单调队列维护最大即可。

C. 魔法咒语

在acam上走,矩阵快速幂一下。有点萌萌了(

D2

A. 喷式水战改

平衡树,大力ddp。

B. 开车

单次查询显然是排序之后对应。这里一个非常好的事情是$\vert x-y\vert$对$x,y$还是比较独立的,因为固定$x,y$的大小关系它就是线性的啦。

考虑时间分块,每一块里面一个车的排名移动量不超过根号,也就是说它匹配的加油站的排名移动量不超过根号。对于一个车$i$,如果它匹配加油站$j$,那么在$j$的一个前缀它贡献$1$,对应的后缀它贡献$-1$,对于加油站也是一样的。每次移动的时候,我们查询一个区间内哪些车的贡献变化了,查询对应的区间内哪些加油站的贡献变化了,然后对于块内改到的所有位置和它们对应的位置爆力特殊处理,块间爆力归并重构。看起来这个查询需要离线双指针。复杂度$O(n\sqrt{n})$,细节大概不会少。

题解给了一个比较带劲的转化,数轴上一个单位长度被覆盖的次数就是前面车和加油站个数差的绝对值。所以就变成区间$\pm 1$,求全局绝对值加权和,这就比较经典了。

C. 同构

这么猛。2hard4me。

2018

D1

A. 求和

模拟,插。或者爆力预处理也行/jy

B. 二进制

考虑什么情况下能重排成$3$的倍数啊。注意到$2^k\bmod{3}=1,2,1,2,…$这样的,所以要求就是如果奇数位放了$a$个$1$,偶数位$b$个,那么$a+2b\bmod{3}=0$。

考虑如果一个区间有至少两个$1$和两个$0$,那么一定行,因为$1100=0,1010=2,0101=1$,也就是说不管剩下的部分是啥,总可以把它调对。这里数组是从左往右写的。

如果不满足上面这个。如果没有$0$,结果是确定的。如果没有$1$,总是可行。如果有一个$1$,那么总是不行。如果有一个$0$,讨论一下如果区间长奇数则可行,否则不行。

然后可以开始大力维护啦。初始化答案是子区间个数,然后减去$0$或$1$的个数$<2$的。维护$0$的连续段,$1$的连续段,对每个$1$维护左右极长$0$长度,每个$0$维护左右极长$1$长度,每次修改变化量都是$O(1)$,平衡树即可。

看看能不能线段树啊。全$0/1$段个数是经典的。恰好一个$0/1$的段个数,再维护第二段极长$0$长度即可。

C. 染色

这么猛。考虑有奇环显然无解。但是有偶环也可能无解。手玩一下样例$1$,发现其实是说两个长$4$的偶环交于两个点,那么我们让两个交点分别是ab,在一侧限制如果是ab就撞,另一侧限制如果是ba就撞即可,那么让ab会撞的方法就是ac连a,bc连b。

然后就不知道我在想啥了。考虑长$4$的环,放ab bc ac cd这样的东西可以让第四个点总是d。任意长度的偶环也是可以的。那么如果两个偶环不交并且能各找一个点使得距离不经过这俩环且是奇数那就死了。距离是偶数的情况,注意到我们可以钦点任何颜色,所以只要反过来就好啦。

考虑两个环有交的情况。如果两个偶环有任意长度的连续的交。如果交的长度是偶数,我们还是在交上放满ab,这样两边一定一边是a一边是b,然后放ac和bc,中间放满cd这样的东西即可。如果交的长度是奇数,手玩一下,比如两个长$6$的环交于$3$个点,我们在交上放满ab,两边分别放ac cd ad和对称地ban掉两个b的东西即可。但是考虑长$4$的环交于$3$个点,看起来它是必然有解的。也就是说交之外的长度必须$>1$才能构造出来。

对于交不连续的情况,我们的构造大多数时候在用ab这样的东西,所以其实没有影响。

这就几乎结束啦。问题是怎么判,首先对每个连通块分开,随便找个dfs树,那么基础环个数就是$m-n+1$对吧。如果$m-n+1=0,1$,那么必然有解。否则先不停剥叶子。如果$=2$,就有至少两个偶环,如果有两个三度点,有解当且仅当剩下是那个两个环在交之外各只有一个点的case,如果是一个四度点,那么就有两个偶环交于一点而无解。如果$>2$,那么必然无解。

D2

A. 治疗之雨

当然dp,每轮我们会有$\frac{1}{m+1}$的概率$+1$,然后有$\binom{k}{i}\frac{m^{k-i}}{(m+1)^k}$的概率$-i$。

那么问题是怎么才能消的快一点。注意到它是一个上海森堡矩阵,所以直接做就$n^2$啦,也就是说我们用$f_i$去消$f_i-1$中的$f_i$这样的。

B. 链上二次求和

考虑一个点的贡献,如果链长是$n$,它在位置$p$,那么包含它的长度在$[l,r]$的区间个数就是

\[\sum_{i=l}^r(\min(p,n-i+1)-\max(1,p-i+1))\]

这个就是计算可能的左端点个数。为了方便一点,差分,现在只剩下$r$。把这个拆开,显然左边被$p=n-i+1$分成两段,右边被$p-i+1=1$分成两段,感觉上我们已经很接近了。

\[\sum_{i=1}^r\min(p,n-i+1)=\sum_{i=1}^{n-p}p+\sum_{i=n-p+1}^r(n-i+1)=(n-p)p+\frac{(p+n-r+1)(r-n+p)}{2}\]

需要特殊处理$r<n-p$的情况,此时它等于$rp$。那个$\max$是一样的。然后就可以求和,带深度的和,带深度平方的和来解决啦。

C. 双人猜数游戏

经典的。枚举答案$n,m$,那么两个人一开始知道$(i<s,j<s)$是不合法的,A知道$ij\neq nm$是不合法的,B知道$i+j\neq n+m$是不合法的。

A表示不知道,说明此时还有不止一种$(i,j)$,所以B可以同时对所有$i+j=n+m$的$(i,j)$一起模拟,A可以对所有$ij=nm$的$(i,j)$一起模拟。如果哪一轮两个人都没有排除任何东西,那就无解啦。这样的话B的初始状态数是$O(k)$,而A看起来跟因数个数有关所以非常低阶,单次复杂度$O(k^2)$。

然后也并不需要这样,我们可以估计一个答案的范围,同时进行所有的模拟,这样就是$O(k^3)$的。

2019

D1

A. 奥术神杖

建个acam先,然后设$dp(i,j,k)$表示前$i$个,走到$j$,匹配了$k$次的最大乘积,复杂度$O(n^3\Sigma)$。

这个东西就是个$\ln$的平均,因为是平均我们希望尽可能把小的扔掉,但是这里有一些固定的位置所以比较麻烦。

考虑二分答案,然后就可以把个数移过去啦,这就$O(n^2\Sigma\log v)$了。但是看着不像能跑过啊?但是就是跑过了。

B. 勘破神机

$n=2$就是fib数下降幂和,转成普通幂,对着通项公式拆拆即可,复杂度大概是$O(k^2\log v)$。那么$n=3$大概也是个线性递推,根据具体数学上看到的奇怪式子的一点印象可以知道它确实是。容易写出一个dp,然后对着它jordan标准化即可,或者直接打表bm,或者直接用gf方法。递推式也是二阶的。

那么具体说一说怎么推吧,做点计算练习!设$f_n$是答案,$g_n$是有一侧多一个的答案,那么枚举最后一列有没有一个竖块,有$f_n=f_{n-2}+2g_{n-1}$,同样的有$g_n=g_{n-2}+f_{n-1}$。$4\times 4$矩阵的jordan标准型看起来就比较阴间。bm的话直接上即可。gf方法就是$F=z^2F+2zG+1,G=z^2G+zF$,需要手动检查一下边界,然后这是一个二元一次方程组。解是$F=\frac{1-z^2}{1-4z^2+z^4}$,虽然有$z^4$,但它是$z^2$的函数,所以这实际上是一个二阶的递推式。

然后强行展开。我们得到$\frac{1}{2(1-az)}+\frac{1}{2(1-bz)},a=2+\sqrt{3},b=2-\sqrt{3}$。$[z^n]\frac{1}{1-az}=a^n$,于是答案就是$\frac{1}{2}(a^n+b^n)$。然后我们要算

\[\begin{aligned} &\sum_i(-1)^i{k\brace i}\sum_{j=0}^l\left(\frac{1}{2}(a^j+b^j)\right)^i\\ =&\sum_i\frac{1}{2^i}(-1)^i{k\brace i}\sum_{j=0}^l\sum_{t=0}^i\binom{i}{t}a^{jt}b^{j(i-t)}\\ =&\sum_i\frac{1}{2^i}(-1)^i{k\brace i}\sum_{t=0}^i\binom{i}{t}\frac{(1-a^tb^{i-t})^{l+1}}{1-a^tb^{i-t}} \end{aligned}\]

这就结束啦,复杂度$O(k^2\log v)$。更牛逼的做法是,注意到对于$m=2$,$ab=-1$,对于$m=3$,$ab=1$,也就是说不同的$a^tb^{i-t}$只有$O(k)$种。爆力计算每种的系数和即可做到$O(k^2+k\log v)$。$a^tb^{i-t}=(ab)^tb^{i-2t}$,我们只需要算每个$(i-2t,t\bmod{2})$的系数和,大概是

\[\begin{aligned} &\sum_i\frac{1}{2^i}(-1)^i{k\brace i}z^i\sum_{t=0}^i\binom{i}{t}\left(\frac{x}{z^2}\right)\bmod{x^2-1}\\ =&\sum_i\frac{1}{2^i}(-1)^i{k\brace i}z^i(1+\frac{x}{z^2})^i\\ =&\sum_i(-1)^i{k\brace i}\left(\frac{1}{2}z(1+\frac{x}{z^2})\right)^i\\ =&\left(\frac{1}{2}z(1+\frac{x}{z^2})\right)^\underline{k} \end{aligned}\]

看起来又变回去了。分治法法即可,复杂度$O(k\log^2 k)$。

C. 送别

这么猛。线段树分治,平衡树维护一下。但是也可以不用时间分治,用时间分治是因为插入删除的时候可能有信息量很大的一段出现或者消失,但是其实消失的时候可以split出去,出现的时候merge回来即可。

D2

A. 排兵布阵

直接大力合并。一眼看上去是$s$个长$m$的物品,实际上是$O(ns)$个长$1$的物品,复杂度$O(nms)$。

B. 光线

classic。dp,设$l(i)$表示从$i$左边来一束光的答案,$r(i)$表示从$i$右边来的答案,那么$l(i)=b_ir(i-1)+a_il(i+1),r(i)=a_ir(i-1)+b_il(i+1)$,边界是$r(0)=0,l(n+1)=1$,要求$l(1)$。容易想到消消,但是$n$很大。考虑这个矩阵非常带状,直接做就是$O(n)$的啦,不过这个直接做比较麻烦,考虑设出$l(1),r(1)$,那么可以解出$l(2)$,还可以解出$l(3)$,于是又可以解出$r(2)$,这样就可以表示所有东西了。

C. 删数

感觉峰哥前几天刚教我这个题。考虑答案是,如果$i$出现$c_i$次,则给$[i-c_i+1,i]$加上$1$,然后数$[1,n]$中$0$的个数。那么全局加减的时候我们不需要全都shift,只需要把查询的这个$[1,n]$ shift一下即可。

2020

只有一题。

A. 封印

这么猛。不过看起来比较经典,建个$t$的sam,然后拿$s$在上面匹配,可以对于每个$r$求出它和$t$的lcs,设为$f_r$。那么问题是查询$\max\limits_{i=l}^r\min(f_i,i-l+1)$,二分答案,st表维护即可。

gdkoi

2023

提高组

D1

A. 太典啦。

B. 错排

收录于 数数从入门到直僵僵地镶嵌在门框里。

C. 异或图

感觉还是比较带劲。容易想到从高到低逐位确定,但是这样我们就需要知道连通性啦,比较没救。

考虑容斥,钦点一些边让端点相同,然后每个连通块选的就不超过其中$a$的$\min$。我们dp出这些连通块,同时直接强行记录哪些点是大小为奇数的连通块中的$\min$,只记奇数是因为大小为偶数的没有贡献。也就是设$dp(S,T)$表示已经决策了$S$中的点,$T$中的点是$\min$的方案数,那么$T$是$S$的子集,所以状态数是$O(3^n)$。转移枚举没选的编号最小的点所在的连通块,那么需要求出每个点集的连通生成子图个数。容斥,枚举编号最小的点所在的连通块,让它和剩下的点不连通,复杂度$O(3^n)$。这样一共就是$O(4^n)$啦。具体一点,$\sum\limits_i\binom{n}{i}2^i2^{n-i}=4^n$。

牛逼优化是,我们每次枚举还没选的部分中的$\min$包含在哪个连通块中,这样$T$中的点必然都比$\overline{S}$中的小。设$T$中的$\max$为$k$,那么$S$必须包含所有$\leq k$的点,设$S$大小为$s+k$。转移的复杂度是$2^{n-s-k}$,状态数则降为$2^k\binom{n-k}{s}$,对$s$求和得到$2^n\left(\frac{3}{2}\right)^{n-k}=2^k3^{n-k}$,总共是$O(3^n)$。感觉很震撼。

D2

A. 游戏

好眼熟。这个题是xxvii poi stage 3 Bieg na orientację。

B. 马戏团里你最忙

也就是每轮有$p$的概率等概率转移到一个超集,$1-p$的概率等概率转移到一个子集,对前$k$轮求每轮在每个$x$概率的加权和。

$n\leq 8$是好做的,矩阵快速幂即可。但是现在$n\leq 17$,好在我们已经知道这是一个线性递推题,但是你发现初值就不会求捏。

考虑怎么$\tilde{O}(2^n)$地迭代一轮。当然是使用法嘛塔。

劲爆的事情是递推式长度只有$O(n)$,这就赢了。爆力多项式取膜即可。为什么只有$O(n)$?不知道。

让我们复习一下怎么求最小多项式。随机两个向量把它压缩到一个数,然后跑bm。

C. 树

长剖先,主要问题是怎么shift一位,也就是所有$d$都$+1$。考虑链怎么做,感觉会链就都会了啊,所以链并不好做!

可以发现的是我们完全不会shift。但是链还是可以做的,考虑枚举一位看它出现多少次,那么相当于每$2^k$个位置交替求$0,1$的个数,可以前缀和一下。于是对于原问题,长剖,维护这个前缀和即可,为了维护它我们需要每个长$2^k$前缀的$k$位的$0,1$个数。复杂度$O(n\log n)$。

发现每条边合并量总是$\log$,所以我们其实不需要长剖,不过维护长$2^k$的前缀和时需要查子树某一层,在bfs序上前缀和即可。

sdoi

2019

D1

A. 快速查询

模拟。

B. 染色

如果没有限制,直接dp即可。如果有限制的话,主要问题是限制的颜色是确定的,而dp的颜色不是。

直接做看起来比较困难。考虑了容斥发现也比较困难,总是需要记两个颜色。

考虑我们强行优化直接做。直接做就是设$dp(i,j,k)$表示第$i$列两个点颜色是$j,k$的方案数。转移是$dp(i,j,k)=dp(i-1,j^\prime\neq j,k^\prime\neq k),dp(i,j,j)=0$这样的。也就是说一个位置从所有位置减去一个十字转移而来,然后对角线上所有位置都是$0$。

考虑我们维护一个行的和和列的和,设$s_x(i,j),s_y(i,j)$是行和列的和,$s_a(i)$是总和,那么转移就是$dp(i,j,k)=s_a(i-1)-s_x(i-1,j)-s_y(i-1,k)+dp(i-1,j,k),dp(i,j,j)=0$。

考虑只处理行的和和列的和的转移。注意到每行每列都只有一个形如$dp(i,j,j)$的位置。

\[\begin{aligned} s_y(i,j)&=\sum_{k=1}^c dp(i,j,k)\\ &=\sum_{k=1,k\neq j}^c\left(s_a(i-1)-s_x(i-1,j)-s_y(i-1,k)+dp(i-1,j,k)\right)\\ &=(c-1)s_a(i-1)-(c-1)s_x(i-1,j)-s_a(i-1)+s_y(i-1,j)+s_y(i-1,j)\\ &=(c-2)s_a(i-1)-(c-1)s_x(i-1,j)+2s_y(i-1,j)\\ s_x(i,j)&=(c-2)s_a(i-1)-(c-1)s_y(i-1,j)+2s_x(i-1,j) \end{aligned}\]

于是我们就做到$O(nc)$了。考虑进一步优化,发现这个相当于全局$\times 2$,一个序列乘一个系数加到另一个序列上,全局加。注意到一个序列加到另一个序列上不好做,于是我们考虑$s_x(i,j)+s_y(i,j)$的转移。

\[s_x(i,j)+s_y(i,j)=(2c-4)s_a(i-1)-(c-3)(s_x(i-1,j)+s_y(i-1,j))\]

然后就做完了。需要注意$(2c-4)s_a(i-1)$是全局和的$c-2$倍,因为每个位置已经被算了两次。套用A的数据结构即可,复杂度$O(n\log n)$。

C. 世界地图

倒过来的话,相当于每次问一个经度区间的mst。不过这个转化不是很好用,因为一个前缀拼一个后缀是个很好的结构。

考虑跑出每个前缀和每个后缀的mst,这个可以用lct搞定。

接下来问题是如何合并两边的mst。可以用严格lct支持可持久化,但是有没有更简单的做法?

注意到我们会加入$n$条边,而这些边连接的是左边第一个点和右边第一个点,左边第二个点和右边第二个点……这样的。先钦点加入其中最小的边,那么剩下的边可能可以进行一些替换。可以注意到它们可能替换的边必然是原来mst上第一次连通 左边某个点和左边某个点 的边,或者右边的这样的,也就是在kru重构树上左边/右边这些点两两的lca构成的集合。把这些边都拿出来就行了。

现在问题是怎么求每个前缀和后缀的kru重构树。一样做就行了,也就是我们新加入一列点的时候直接跟前面的虚树上的点对应的边一起重新跑kru重构树。复杂度$O((m+q)n\log n)$。

D2

A. 热闹的聚会与尴尬的聚会

限制等价于$q(p+1)\geq n,p(q+1)\geq n$。

样例没有无解,所以直接猜测必然有解。

我们可以不停删度数最小的点直到没有点来找到最大的$p$。接下来我们需要找到一个大小足够大的独立集。

考虑怎么才能凑出一个长的像$pq$这样的东西。

考虑一个离奇想法,注意到我们继续不停删掉度数$=p$的点,就不会剩下任何点了,那么按照删掉的顺序,我们每选一个点会ban掉后面不超过$p$个点,于是贪心即可。

B. 移动金币

考虑如何判定一个局面是先手必胜还是后手必胜。

一个前置知识是Staircase Nim。这个转化比较有趣,我们考虑空位的移动,发现它就是Staircase Nim。于是问题变成从右往左数第奇数个间隔的长度的xor和是$0$的方案数。

然后可以$O(n^2m)$状态的dp,这个看起来很困难。考虑如何优化,问题相当于选$\frac{m}{2}$个数,和不超过$n-m$,并且xor和为$0$的方案数,偶数位置的可以隔板一下。

考虑数位dp,设$dp(i,j)$表示前$i$位xor和都是$0$,并且总和是$j$的方案数。转移就是枚举这一位有多少个选了,看起来选的个数必须是偶数。复杂度$O(nm\log n)$。

C. 连续子序列

不可能会。

这个序列叫Thue-Morse序列。

一个经典结论是,以下几种方法都定义了这个序列 :

  • $a_{2n}=a_n,a_{2n+1}=1-a_n$$

  • 从$0$开始,每次把$0$变成$01$,$1$变成$10$$

  • $a_n$是$n$的popcnt的奇偶性

  • 从$0$开始,不断把整个序列取反之后的结果接在序列后面

考虑如何判定一个串是不是thue-morse序列的子串。使用第二个定义的话,我们只需要知道开头是奇数位还是偶数位,就可以直接这么操作把它操作回去。进一步地,如果串长至少是$5$,那么必然存在两个相邻的相同字符,不从这里断开则必然不合法。于是我们可以$O(n)$检查一个长$n$的串,但是这个有啥用啊(

注意到对于串长至少是$5$的串,其中必然包含两个连续的相同数字,所以划分直到串长$\leq 4$的方案是唯一的。设$dp(s,i)$表示串$s$后面接了$i$个字符的答案,那么如果$\vert s\vert+i\leq 4$则爆力,否则递归两种划分方案。当$\vert s\vert\geq 5$的时候只有一种方案,而当$\vert s\vert\leq 4$的时候只有$O(1)$种$s$,于是状态数是$O(s+\log k)$。用map记搜即可。

2022

D1

A. 整数序列

当然根号分治,两侧都小的直接做,一侧大的,拿小的去大的里跑,往左匹配最近的,往右匹配最近的,那么能用到的只在这里面。所以其实不需要显式根号分治。

B. 进制转换

数位dp,但是我们不能同时对二进制和三进制数位dp。

考虑折半吧,那么低位的二进制和三进制表示都只有一半对吧,也就是说加入低位只会对高一半产生最多$1$的进位。但是低一半的变化量可能非常大。

可以想到现在已经会了$n^\frac{2}{3}$之类的东西了。

考虑对低一半进行dp,决策三进制的每一位选什么,然后对二进制是否到高一半有进位都处理出答案。这就赢了。

C. 子串统计

建立基本子串结构,每个块内的occ都是相同的,直接按japanese knowledge分治法法即可。

D2

A. 小 N 的独立集

直接dp。

B. 无处存储

对树$\log$大小分块,然后对收缩树树剖。

C. 多边形

收录于我的洛谷blog。直接粘过来了!

考虑 $n$ 个点的多边形三角剖分的数量是卡特兰数 $C_{n-2}$ 。这里的不同在于,同一条边上不能连,并且有一些点可以在三角形的边上(但是不能一整条边都没有被连到)。

考虑为了处理第二个,我们对于每条边枚举上面有多少点,然后组合数选出来。现在问题是同一条边上不能连。考虑容斥,可以注意到现在各边是独立的,它们之间全靠那个卡特兰数拼起来,所以我们只需要考虑一条长 $l$ 的边应该分配何种容斥系数,然后把它们的ogf分治呐塔塔卷起来就好了。

发现直接对 任意两点之间没有线 容斥看起来是不彳亍的,因为直接钦点的话这些线可能会交叉,看起来它很复杂。可以想到对 任意一点不被一条线跨过 容斥,但是这个看起来和上一个没啥区别。

考虑一个牛逼想法,我们对 没有一条线连接相隔一个点的两个点 容斥。可以发现如果一个方案包含同一条边上两个点之间的线,那么它就把这条边的一部分和外部隔开了,而这里面还会被完全剖开,所以必然存在一个三角形,也就是连接相隔一个点的两个点的线。这个东西的好处是它看起来非常局部,我们可以直接把这个三角形挖掉再上卡特兰数。我们钦点一些这样的线,设它的ogf是 $T(z,t)$ ,其中 $z$ 表示总边数而 $t$ 表示挖掉那些三角形之后的边数,可以写出 $T=1+t(zT-z^2T)$ ,也就是决策最后一个点怎么连,于是 $T=\frac{1}{1-t(z-z^2)}$ 。

但是算完这个好像还没结束,因为我们还需要考虑留下了多少个点。

\[\begin{aligned} &\sum_{i=0}^{a-1}\binom{a-1}{i}[z^{i+1}]T\\ =&\sum_{i=0}^{a-1}\binom{a-1}{i}[z^{i+1}]\frac{1}{1-t(z-z^2)}\\ =&[z^a]\sum_{i=0}^{a-1}\binom{a-1}{i}\frac{z^{a-(i+1)}}{1-t(z-z^2)}\\ =&[z^a]\frac{1}{1-t(z-z^2)}\sum_{i=0}^{a-1}\binom{a-1}{i}z^{a-1-i}\\ =&[z^a]\frac{(1+z)^{a-1}}{1-t(z-z^2)} \end{aligned}\]

于是问题就是最后这个式子。为了把 $t(z-z^2)$ 拆开,考虑对 $F=z-z^2$ 进行拉反,我们计算它的复合逆。为了凑出一个不带二次项的东西,首先配方成 $1-4z+4z^2=(1-2z)^2$ ,然后就结束了,所以它的复合逆是 $G(z)=\frac{1-\sqrt{1-4z}}{2}$ 。然后考虑如何表示 $(1+z)^{a-1}$ ,它看起来就是 $(1+G(F))^{a-1}$ ,这可真是太直接了,不过为什么感觉很爽啊?所以我们知道这里 $H$ 就是 $H(z)=\frac{(1+G(z))^{a-1}}{1-tz}$ 。反一手。

\[[z^a]\frac{(1+G(F))^{a-1}}{1-tF}=[z^a]\frac{(1+G)^{a-1}}{1-tz}G^\prime\left(\frac{z}{G}\right)^{a+1}\]

那个 $\frac{1}{1-tz}$ ,我们最后枚举 $t$ 的次数,问题就是要求出剩下的东西的乘积。但是这个 $(1+G)^{a-1}$ 看起来不是很好办啊?可以注意到 $G$ 跟卡特兰数看起来很像,实际上它就是 $z\mathcal B_2$ ,可以用广义二项级数的结论来做,据说可以线性。不过如果不知道广义二项级数,由于$G$的复合逆$F$很简单,我们可以再对$(1+G)^{a-1}$和$\left(\frac{z}{G}\right)^{n+1}$进行拉反。为了练习我实践一下。先来看$(1+G)^{a-1}$ :

\[\begin{aligned} &[z^n](1+G)^{a-1}\\ =&\frac{1}{n}[z^{n-1}]((1+z)^{a-1})^\prime\left(\frac{z}{z-z^2}\right)^n\\ =&\frac{1}{n}[z^{n-1}]\frac{(a-1)(1+z)^{a-2}}{(1-z)^n} \end{aligned}\]

,可以一次卷积求出。再看 $\left(\frac{z}{G}\right)^{n+1}=\left(\frac{F(G)}{G}\right)^{n+1}$ :

\[\begin{aligned} &[z^n]\left(\frac{F(G)}{G}\right)^{n+1}=[z^n]\frac{(z-z^2)(1-2z)}{z(1-z)^n}=[z^n]\frac{(1-2z)}{(1-z)^{n-1}} \end{aligned}\]

,可以线性。所以分治呐塔塔把这些卷起来,然后乘上卡特兰数就结束了。

zjoi

2022

D1

A. 树

考虑我们从左往右决策每个点是不是叶子,那么一个点可以在前面不是叶子的点中随便选父亲。但是第二棵树是倒着的,这就不是很好。

考虑钦点出后面有多少个点是叶子。这就好了。但是还有一个问题,就是我们钦点出来的叶子可能不是所有的叶子,也就是说不是叶子的点不一定真的有儿子。

继续大力钦点,我们记录现在是第几个点,第一棵树上前面有多少个钦点为不是叶子的还没有儿子,第二棵树上后面有多少个叶子,有多少个不是叶子的还没有儿子。复杂度$O(n^4)$。

考虑怎么砍一维,感觉不太好办。没有办法的话就考虑容斥,我们钦点一个位置是不是被错误地选成了叶子,于是钦点为叶子的和钦点为错误的叶子的的数量就可以合起来放在一维里,复杂度$O(n^3)$。

B. 众数

也就是我们可以选择一个区间,然后选择区间内的众数和区间外的众数拼起来。

首先我们选的这个区间,两端必然可以都是区间内的众数。于是考虑根号分治,少的数只给出$n\sqrt{n}$个可能的区间作为答案。

考虑多的数$x$作为区间外的众数的情况,我们把$x$看成$-1$,把另一种数$y$看成$1$,那么也就是要找一个最大子段和。同时对每个$y$维护当前的某种前缀和,加入$y$的时候,如果前缀和是负的则把它先置$0$,然后更新答案即可,加入$x$的时候则是全局$-1$。对于多的数作为区间内的众数的情况,也就是反过来了,看起来做法是一样的。

那么考虑少的数$x$作为区间外的众数的情况。我们知道这个区间端点的两侧可以都是$x$的一次出现,那么也就是求自己笛卡尔积自己的区间众数,但是这个看起来不是很好做。不过好消息是这个区间众数的出现次数不超过根号。考虑对于每个左端点预处理最小的右端点满足众数出现次数$\geq k$,双指针扫扫即可。总复杂度$O(n\sqrt{n})$。

C. 简单题

一般图上这是#p complete的,我们每条边给一个大约$2^\binom{n}{2}$的边权就可以归约哈密顿链计数啦(因为这里用到的数的长度还是多项式级别的),所以一开始这个条件居然是重要的。

v-dcc之间看起来没有影响。考虑一个v-dcc可能是啥样的。考虑如果两个环有超过一段交,那么因为边权全是正的,这个可以推出一些边权是$0$,所以就不可能了。如果任意两个环只有一段交,如果有一个环,它和另外某两个环的交不完全相同,也是不可能的。那么也就是说所有的环都交于同一条链,此时相当于两个点之间有若干条不交的链,这个肯定是可以的,这种图好像被称为 杏仁 或者 纺锤体。

这一段的推导不是很对。但是我懒得remake了!

现在,爆力的话,要算从纺锤体一个点走到另一个点的方案数,那么我们走的路径一定是,如果在同一条纺锤丝上,可以直接冲过去。如果没有直接冲过去,那么必然先到达纺锤体的一极,于是就是ban了一条链之后一极到某个点的答案了,或者我们更多地枚举就是ban两条链之后两极的答案。如果是同一极那么我们选偶数条链排列,否则选奇数条,可以分治法法法出来。但是这个处理不了lca处的问题,感觉需要在平面分治结构或者平面扫描线上法法捏。

你是不是没有看懂我在说什么啊。妈的,怎么是权值和啊?那么考虑权值和怎么做,我们就只需要方案数了,所以可以直接预处理出来,复杂度就是线性的啦。

D2

A. 面条

这么猛。考虑$n=2^k$怎么做,发现$\log$轮之后就变成全部相同的了。那么考虑$n=98304=3\times 32768$,发现最后会剩下$[1,65536],[65537,98304]$两段,然后可以矩阵快速幂求出每一时刻两段分别是啥。但是这东西好像没啥用。

考虑$n=500$怎么做,因为是稀疏的线性递推,可以bm一下。$5\times 10^3$大概是一样的做法。

这个东西必须得有点用啊!猜测最后只会剩下$\log$段。我手玩了一下$n=18$之类的,看起来如果$n=2^kt$,$t>1$,那么$k+1$轮之后会有$\frac{t-1}{2}$个长$2^{k+1}$的段和最后的一个长$2^k$的,$t=1$则需要特判。设$l=\frac{t+1}{2}$为段数。强行考虑发生了什么,看起来如果每一段分别是$a_i$,$a_l$是那个长$2^k$的段,那么它就变成$\frac{1}{2}(a_1+a_l,a_1+a_{l-1},a_2+a_{l-1},…,a_\frac{l-1}{2}+a_\frac{l+1}{2},2a_\frac{l+1}{2})$。扔掉$\frac{1}{2}$,经典地考虑差分,令$b_i=a_i-a_{i-1},a_0=0$,那么前者操作后的$b$就是$a_1+a_l,a_{l-1}-a_l,a_2-a_1,…,a_\frac{l+1}{2}-a_\frac{l-1}{2}$,用$b$表示就是$b_1+\sum b_i,-b_l,b_2,-b_{l-1},…,b_\frac{l+1}{2}$,于是这非常接近一个置换了。$a_l=\sum b_i$很是不好,牛逼做法是我们直接把它扔掉,因为知道$l-1$个差分和总和(总和每次翻倍)还是可以还原整个序列。类似地考虑长$2^k$的段在最前面的情况,爆力计算可以知道它对差分的影响和$2^k$段在最后的情况的区别就是交换了相邻两项。建一个两层的图表示正负,现在我们会$q\leq 50$了。

现在考虑这个变换有啥性质,因为没性质还是不能做啊。只剩$\log$段大概是不对的。考虑为了解出某个$a_i$我们到底需要啥信息,所有数的和中$b_i$会贡献$l-i+1$次,那么$b_1=s-\sum\limits_{i=2}^l b_i(l-i+1)$,而$b_1=a_1$,$a_i=a_1+\sum\limits_{j=2}^i b_j$。也就是说我们要求一个带下标作为系数的和和一个前缀和。爆力考虑这个变换在干啥,看起来它会把$1,…,l$变成$-l,1,-(l-1),2,-(l-2),3$,发现前一半的数位置都翻倍了。考虑一个牛逼构造,我们把数排成$1,…,l,-l,…,-1$,然后把$i$换到$2i\bmod{2l+1}$,看起来正好就是这个置换,非常猛兄弟!

那么接下来所有环的长度都是$\mathrm{ord}_{2l+1}(2)$的因数,我们爆力对每个环长$d$算一下贡献,于是每个查询都可以膜$d$,也就是说只有$d$种查询。对于每个查询,要查环上那个前缀中的位置的和,以及每个位置带一个位置的权的和,看起来前者也是某种带权和嘛,看起来这就是膜环长的循环卷积,可以法法一下做到$O(n\log n)$。然后每个环爆力贡献给膜$\mathrm{ord}_{2l+1}(2)$的所有余数,这个复杂度是经典的$O(n\log\log n)$。总共是$O(n\log n+q+\sqrt{v})$,最后那个是$\sqrt{v}$进制快速幂的预处理。

B. 计算几何

典题/cf

菱形划分,完美匹配,最大独立集,原来都是你。

SyadouHayami老师的图很好。

C. 深搜

设$dp(u,v,k)$表示从$u$到$v$,$\min=k$的概率,转移枚举进入$v$子树前走的子树$\min$的$\min$,那么更小的子树不能走,更大的子树是自由的。

三维的状态看起来没啥救,考虑枚举$k$,差分一下计算$\min\geq k$的概率的和,也就是说所有点都$\geq k$的概率。

先考虑固定一个$k$咋做,设$dp(u,v)$表示从$u$到$v$,不经过$<k$的点的概率,转移的话,如果一棵子树全都$\geq k$,那么可以走,否则不能走,考虑走进$v$所在子树之前没有走任何不能走子树的概率,如果有$s$个儿子,$c$个别的子树可以走,这其实相当于随机一个儿子的排列然后从前往后扫对吧,那么可以走的$c$个子树其实锤子用没有,所以概率就是$\frac{1}{s-c+1}$。此时同一子树的转移都是一样的了,设$S_{dp}(u)$表示$dp(u,v)$的和,那么就有$S_{dp}(u)=\sum\limits_v S_{dp}(v)f(s,c-[v\text{ 可以走}])$。

从大往小扫$k$,那么每个点只会从不可以走变到可以走一次。动态dp即可。

cnoi全国

noi

2022

D1

A. 模拟

直接做。需要哈希表启发式合并来check一个数的出现次数,或者你可以线段树合并,然后就结束了。

B. 移除石子

不太会造自动机啊!

考虑我们第一种操作可以,呃好像其实没太有必要,第二种操作可以只用长$3,4,5$的。也就是说$5$堆前的都没有用了。

考虑一堆如果超过$14$,那么它相当于只有$14$,因为只有$3+4+5$个第二种操作可以覆盖它,否则它必然被一次第一种操作覆盖。更紧的界是$5$,可以对拍出来。

然后我们就可以造一个nfa了。搜出所有可达状态然后最小化即可。当你造了nfa但是状态数很大的时候,不要powerset,直接搜出可达状态。

C. 树上邻域数点

top tree。遗憾离场。

D2

A. 树哈希

除了$k$棵子树以外必然全部直接匹配,爆搜这些子树怎么配。

B. 冒泡排序

先做 abc262 Ex. Max Limited Sequence。收录于 usaco 18~19 Jan. Pt 那一套里面。

考虑性质B,也就是有一些位置确定了,那么剩下的数我们放的一定是递增的,因为画一画可以发现交换一对逆序对不会让逆序对数增加。

考虑该怎么放这些数,既然是递增的,那么这里面不会产生逆序对,那么我们让每个数跟确定的数产生的逆序对数最小,这样得到的结果也确实是递增的。

考虑性质C,因为交换一对逆序对不会让逆序对数增加,而一个$\min=k$的区间必然所有数$\geq k$,所以让第一个数是$k$必然不劣。然后按性质B填即可。但是这里有问题,因为没有确定的数还有一个$\geq$某个数的限制,考虑如果$i<j$,$i$的限制比$j$要小,那么填的也是$a_i\leq a_j$的。如果$i$的限制比$j$大,就有问题了。考虑怎么让它没有后效性一点,感觉不太行。

猜测直接从左往右扫,贪心让跟所有一开始就确定的数和左边已经确定的数新产生的逆序对数最小即可。证明考虑如果选更大的数肯定不优,因为是从前往后选;如果选更小的数,这里每个数是有决策单调的,而因为是$\geq$某个数的限制,我们可以把后面选的数改大而不增加逆序对数。

考虑性质A,如果一个区间的$\min=1$,也就是说全都$=1$了。如果$\min=0$,我们还是让第一个不必须为$1$的为$0$。然后按性质B填即可。现在拼一拼有72分了!

考虑整个问题,从大到小扫值域,每次让一个尽可能靠前的数满足限制。然后按性质C填即可。

C. 二次整数规划

什么牛逼东西。

ctt

2012

D1

A. 楼房重建

classic。

B. 序列染色

集训队胡策

这里的年份是出题人属于哪届noi的集训队。

2018

R1

A. 完美的队列

因为这里是全局颜色数,只需要对每次操作求出它在何时被全部弹掉,然后胡乱扫扫即可。

把操作插到线段树里,那么一个操作被全部弹掉的时刻就是拆出来的各区间被全部弹掉的时刻的$\max$对吧。考虑处理一个点上所有的操作,子树内会有一些操作,到根的链上还会有一些操作,前者的总量是$O(n\log n)$,而后者都完整地覆盖了这个点。显然这个点上先进来的操作先被弹没,所以可以双指针,我们轮流考虑以下几件事

  • 当前考虑的操作被弹没。

  • 子树中或当前结点上发生了一个操作。

  • 到根的链上发生了一个操作。

第三种可以线段树上二分出进行了多少次,所以复杂度只跟前两种事件的个数相关。然后就,开个线段树去维护当前考虑的操作在每个位置都被推到哪了,也就是一开始插入的时候$i$位置是$a_i$,然后每个操作是全局$-1$或者区间$-1$,维护$\max$,如果$\max>0$就说明还存在。考虑如何快速移动到下一个操作,注意到我们其实只是在$-1$,它是交换且有逆的,所以只需要把两次插入之间的操作全都用$+1$给revert回去,那么这样每个事件只会被revert一次,这也是为什么双指针有用。复杂度$O(n\log^2 n)$。

2020

R1

A. 太阳神的宴会

造个dfa先,这个dfa显然就是在每个串上匹配尽可能长,因为两个串相似,对应位置的子串也相似。那么我们就是想要一个sam之类的东西对吧。注意这里st是不行的,因为它其实没有压缩状态啊。

考虑我们把这个相似转化成相等。容易想到记这一次出现到上一次出现的距离,没出现过则记$0$,这样截取子串的时候只有每个字符的第一次出现会变化,截取前缀的时候压根不会变化。还要拼接,注意到拼接的时候每个串的置换是独立的,相当于右边那个串的$0$是通配的,这就赢了。

吗?$0$其实不是通配的,因为$0$也只能填到前面某个字符最后一次出现的距离,这样我们需要的信息量就太大了。

考虑能不能让字符集简单一点。注意到$s$和$t$之间非常不对称,我们可以在对$s$的预处理中记很多东西,但是$t$不行。考虑直接对最后一次出现构造 : 列出前面所有字符的最后一次出现,如果$s_i$是第$k$近的,我们在$i$这里记一个$k$,没出现过则记$0$。这样我们只需要额外知道前面有多少种字符出现过,也就是有多少个$0$。那么我们已经会$O(L^2\Sigma)$了,只需要记录$t$中有多少个$0$,对每种个数爆力建后缀trie即可。

接下来考虑如何建立sam。sam是,先建立后缀trie,考虑定义一个串的suffix link是它去掉左边的字符,这形成了一棵树,可以发现只有一个儿子且不是前缀的点可以和儿子缩成一个,因为它们的endpos集合是相等的。这样点数就是suffix link树的叶子个数级别,这个个数也就是左边不能加字符的串的个数,也就是所有前缀。回来考虑这个题,我们还是认为suffix link是它去掉左边的字符,这比sam复杂了一点,如果一个字符是整个串中最后一次出现了,那么它作为最左边的字符被去掉的时候,就不能和它的suffix link缩成一个,因为它们后续的转移不同,除此之外后续的转移还是相同的。那么相当于我们在suffix link树上断开了$O(n\Sigma)$条边,这样最小化之后是$O(n\Sigma)$个状态。考虑如何求出转移,一个想法是直接最小化,先求出sam,然后每次找到一条被断开的边进行分裂,但是这要求我们动态定位某个串属于dfa上哪个状态,这就寄了。考虑直接跑blumer sam,跳suffix link的时候注意一下这是不是真的suffix link即可,但是转移数量太多,复杂度$O(n\Sigma^2)$。

更好的做法是,注意到后续转移只跟这个串中前面有几个$0$有关,并且区别只有前面的$0$更多的状态,$0$的转移可以连向更多地方,以及可用的字符更多。可以直接用一个后缀和来做,而不需要显式把dfa全建出来。复杂度$O(n\Sigma)$。

2021

R4

A. 基础图论练习题

太你妈牛逼了。

kru。转化为算连通块数的变化量。

考虑$a=2,b=0$,这个看起来好像在poi见过,根据周期引理,加入$d_1,d_2$两组边,如果$d_1+d_2-\gcd(d_1,d_2)\leq n$则会形成$\gcd(d_1+d_2)$个连通块,否则会形成$d_1+d_2-n$个连通块。也就是说会形成$\max(d_1+d_2-n,\gcd(d_1,d_2))$个连通块。

考虑$b=0$。看看srm 600.5 B. Huge Graph咋做啊。这个题意大概是给一组边求连通块个数。题解贺自jiangly。

考虑把$d$从小到大排序,那么$d_1$就是最小的,$u\rightarrow u+d_k$的边可以用$u\rightarrow u+d_1\rightarrow u+d_k$拼出来,也就是说我们可以给每个$d_k$都减去$d_1$而不让连通性变弱,但是连通性可能会变强。然后比较神秘,考虑我们只给$u\leq n-d_k$的点从$u+d_1$连到$u+d_k$,这样$u+d_1$本来就可以经$u$中转到达$u+d_k$,所以连通性肯定也不会变强啦。此时也就是前$d_1$个点没有连任何$d_k-d_1$,那么它们都是只有一条向后的$d_1$边,呃也可能有的点满足$u+d_1>n$,此时它直接没有边。于是我们可以把前$d_1$个点删去,这就恢复了图最初的形式。如果$d_1=0$,那么s把它扔掉,如果$d_1>n$,那么结束。可以把$d_1$相同的一起做完,那么每次要么$d_2\leftarrow d_2\bmod{d_1}$,要么$n$减少到原来的$\frac{2}{3}$,由于 如果发生取模则必然折半,$d_1+d_2$不超过原来的$\frac{3}{4}$,用堆维护,复杂度$O(a+\log n\log a)$。

回到这个题的$b=0$,也就是要支持加入一组边。可以注意到只有$\log n$组边对连通性有贡献,所以只需要把它们拿出来和新边一起重新跑。复杂度$O(a\log n\log\log n)$。

考虑一般情况。我们先处理完所有$a$边再处理$b$边,$b$只会把$a$部分给出的mst上的一些边换下来,这只需要求出$a$部分给出的kru重构树上$b$中出现过的端点的虚树。但是我们不太好直接找到何时发生合并。但是找到一个点在哪个连通块还是容易$O(\log n)$的。

考虑整体二分出每次合并及合并的时刻,并以此建出kru重构树。在区间中点算一个连通性,把每个连通块分开递归左边算出对应的kru重构树,每个连通块的一个代表元放在一起递归右边,并按右边的重构树合并左边的连通块们。mst上每条边只会递归进一边,所以一层的总点数不超过$2b$,所以这部分复杂度是$O(b\log n\log a)$。

B. 机器

感觉很厉害。

容易搞一个费用流。先做类似于 把$h$加进$a,b$里面,并把$a,b$都取负 这样的事情。对偶,设$x_{i,j}$表示$s\rightarrow i$第$j$条边的流量,$y$表示$i\rightarrow t$,$f_{i,j}$表示图上的流量,那么原问题看起来是这样的

\[\sum x_{u,i}-y_{u,i}+\sum_{v\rightarrow u}f_{v,u}-\sum_{u\rightarrow v}f_{u,v}=0\operatorname{forall}u\\ x_{u,i}\leq 1\\ y_{u,i}\leq 1\\ \max\sum a_{u,i}x_{u,i}+b_{u,i}y_{u,i}\]

经典的,相等限制对偶成一个没有非负限制的变量。让第一类限制对偶成$z$,第二三类分别对偶成$f,g$,我们大概会得到

\[f_{u,i}+z_u\geq a_{u,i}\operatorname{forall}u\\ g_{u,i}-z_u\geq b_{u,i}\operatorname{forall}u\\ z_u-z_v\geq 0\operatorname{forall}v\rightarrow u\\ \min\sum f_{u,i}+g_{u,i}\]

固定一组$z$,那么$f,g$的选择是简单的,也就是$f_{u,i}=\max(0,a_{u,i}-z_u)$,$g$同理。

这是一堆下凸函数的和。$z_u\geq z_v$让我们想起保序回归,发现因为是凸的,这玩意和保序回归性质差不多。这里因为是费用流对偶,必然存在一组最优解全是整数,在整数上整体二分即可。

C. 数列重排

是不是简单找规律题啊。考虑$x=1,s=0$咋做,我们把$0,…,k-1$排在中间,剩下的均分到两边即可。

考虑$k=1$咋做,此时相当于只有$0,1$,那么相当于最小化全$1$的区间数,我们把$0$均匀地插到$1$之间即可。

考虑$l=r=m$咋做,发现我们可以让任意长$m$的区间都包含$0,…,m-1$,方法是如果$s$中没有$1$,直接把任意一个排列重复$x$次,如果有$1$,我们在排列中把$1$放在前面,最后放一次不完整的即可。

可以注意到所有$<k$的数构成的子序列必然可以是这样的。我们可以把$\geq k$的数都看成$1$,$<k$的数都看成$0$,一个区间合法当且仅当至少有$k$个$0$。

可以注意到两个性质。

  • 如果两个$1$之间不足$k$个$0$,把其中贡献小的移动到贡献大的旁边不会让答案减小。

  • 如果一个$1$左边不足$k$个$0$,把它移到最左不会让答案减小。

也就是说最后一定是一段$1$,一段长至少$k$的$0$,一段$1$,一段长至少$k$的$0$,这样下去。那么对于每个$1$,有且只有它这一段$1$和左右前$k-1$个$0$到它是不合法的。端点都是$0$的区间是否合法与$1$的排布没有关系。转而最小化不合法的段数,问题变成中间的一个$1$的贡献是所在段长度加上$2(k-1)$,两边的只加$k-1$,最小化总贡献。

如果有$c$个$0$,我们分为$\lfloor\frac{c}{k}\rfloor$段,两段之间可以没有$1$,每一段的长度是不重要的。那么也就是说有$\lfloor\frac{c}{k}\rfloor+1$个位置可以放$1$段。中间的全部平等,两边的平等,大家都是凸的,分开做然后闵和即可。复杂度线性。

2022

R1

A. Astral Brith

ix35牛逼。这个题曾被chz搬入ytez秘制模拟赛。

转而考虑不在lis中的数,我们把它们都扔掉,剩下的数会形成若干段,这个段数$-1$几乎就是需要的步数,$-1$是因为有一段可以是前一半0后一半1,几乎是因为还需要考虑整个序列前面全1后面全0的情况,不过我们先不考虑它。

考虑先把相同的一段缩成一个,显然相同的一段要么都扔要么都留。我们在中间扔一个数,会合并两边,于是减少了两段,而扔两边则只减少一段。如果直接贪心选可能会扔相邻的两个,此时减少的段数是错误的,但是显然相邻的两段不会同时被扔,因为只扔一段就可以把另一段并入别的一段。看起来不能选相邻的两个是经典反悔贪心问题,枚举两边扔不扔,我们就知道要选多少个中间的,然后按经典问题做即可。

B. 复读程度

压缩sam入门题。

考虑这个东西是啥东西,它就是正串sam suffix link树一个子树和反串sam suffix link树一个子树的交,减去根上一些过短的串。对于前者,当然dfs序,于是就是二维数点啦,这里平面上每个点权值是正串sam一个点和反串sam一个点的交的权值。容易知道这样的交只有最多一个串,否则如果有两个串,短的必须是长的的border,这就让它们的beginpos endpos都不同了。

考虑莫队,差分成四个 前缀和前缀的笛卡尔积,那么每次在正串dfn上移动,就是查询正串sam一个点和反串sam一个dfn前缀的笛卡尔积的权值和,反串是对称的。

建立压缩sam。经典的(看起来至少在 子串统计 中出现过),我们把每个点中包含的串,第一个beginpos作为横坐标,第一个endpos作为纵坐标画到平面上,这会得到一个上下轮廓线都单调的形状,并且压缩endpos等价类的正串sam上每个点对应一行,压缩beginpos等价类的反串sam上每个点对应一列。所有这些形状称为 基本子串结构。那么这个莫队的查询,我们找到正串上那个点在压缩sam哪个点中,就是查询它对应的那一行中反串sam上dfn在某个前缀的点的权值和,那么由于一行是一个区间,这是一个二维数点。有$O(n\sqrt{n})$次查询,所以二次离线,根号平衡即可,复杂度$O(n\sqrt{n})$。

C. 树

考虑subtask 3怎么做。每个点跟所有点查一次就得到重心。然后问题是怎么把所有点划分到子树中。查一遍得到重心的邻接点,那么如果$u$在重心$c$的$v$一侧的子树中,它到$c$的距离是$d$,那么到$v$的距离是$d-1$,到重心其它邻接点的距离都是$d+1$,于是就可以二分了。查询次数$O(n\log^2 n)$,总长$O(n^2)$。

我们需要给重心的邻接点建一个平衡的分治树。为了求出子树大小,我们拿重心的每个邻接点跟所有点查一下,就可以解出这个邻接点一侧的子树大小。这样查询次数就$O(n\log n)$了,并且感觉上常数还是很小吧,问题是怎么砍查询总长。

容易想到随机一些点来估计这个到所有点的距离和。感觉上卡卡就非常对啊!但是题解管这个叫不卡常我不是很理解。

R2

A. Range Minimum Element

考虑什么样的$b$是合法的。大家都知道noi22 D2B,如果不知道的话,$\min=k$就是所有数$\leq k$且至少一个数$=k$,那么我们每个区间做一个对$b$取$\max$,如果全部取完之后$\min$是对的那就行,否则不行。于是开始枚举扫描线方向。考虑找到$b$最小的那个区间,那么它里面有个位置需要等于它,枚举这个位置,跨过它的区间必须也选这个值,而没跨过它的区间看起来没啥影响,只是不能选更小的了。但是$b$最小的区间,钦定完了我们还得枚举最小值在哪,所以不如直接考虑$a$的最小值在哪,发现这其实是简单的,枚举一个位置,如果它没有被覆盖,一开始我们就先把这种删掉,分成几段递归下去。否则我们要求要么它前面不能有比它更小的,那么也就是都要被一个比它大的区间推掉,也就是说完全包含在前面的区间的并必须是整个前面。而后面就比较随意啦。

当然猜测它是关于$i$的$O(r-l)$次多项式,复杂度$O(n^4)$。

B. 相等树链

容易想到点分,但是点分完了咋做捏。在$T_1$上点分,每次合并两个分治块,在$T_2$上这些点会形成若干个连通块,连通块间显然不能连,连通块内可能可以连。

考虑 是一条链 到底是啥,我们给每个点处理出它到分治中心的链上的点在$T_2$上最小的覆盖它的链(包含分治中心。这是因为一会你会看到它的作用),如果没有这样的链那么这个点就没用啦。这个东西也就是,如果原来是$(u,v)$,现在要插入$w$,那么如果$w$在$(u,v)$上就不用改,否则看$u$在$(v,w)$还是$v$在$(u,w)$上。判断一个点在不在链上,可以判断三个点的y-center是不是它自己,所以其实我们是求三个点的y-center,如果它不是$u,v,w$中一个那就不行啦,否则取另外两个作为新的链。

然后考虑两条链如何拼接。首先如果求出点数应该是多少,直接用点数判是不是满的即可。设分治中心是$c$,现在问题是$T_2$上有$A,B$两组链,每条链都包含$c$,你要求在第一组选一条,第二组选一条,点数之和$-1$恰好是链并长度的方案数。当然以$c$为根考虑。如果一条链包含另一条,听起来比较好做,可以写成两个子树的笛卡尔积,扫描线线段树套hash table即可。如果两条链不互相包含,我们枚举$A$中的那条链,设它是$(u,v)$,在虚树上走,走到$u$的时候计算另一条链的一端在$v$子树,另一端在$u$到$c$链上的贡献,那么第二个限制在树上走的时候可以自然地维护,于是这是一个动态一维数点,线段树套hash table即可。复杂度$O(n\log^2 n)$。这里不需要真的建出虚树来,只需要虚树的dfn即可,所以还是挺简单的!

感觉题解看起来就比较带劲。我们在$T_2$上标记每个点来自$A$还是$B$,一个点$u$到$c$链上的来自$A$的集合记为$a_u$,$b_u$同理,那么$A$中那条链就包含$s_a=a_u+a_v$,$B$中那条链就包含$s_b=b_u+b_v$,它俩的交是$a_u+b_u,a_u+b_v,a_v+b_u,a_v+b_v$中的一个,这个交要等于$s_a+s_b$,发现其中只有最多一个等于$s_a+s_b$,所以就可以移项变成$s_a-a_u=b_u-s_b$了,hash即可。对于包含的情况也可以直接这么做。

C. nth

好像是经典问题!90个bit有点惊悚。第$c$小就是比它更小的数$<c$个的最大的数,A二分答案$d$,B告诉A这边有多少$<d$的数,然后A告诉B $d$是大了还是小了,这样位数是$\log^2$的。B可以每次告诉A这一次的和上一次的差,这样位数除一个$2$,大概可以获得45pts。

注意到如果这一次差了$k$,那么我们可以多排除$\frac{k}{2}$个数。但是这个感觉并不能再除一个$2$。

考虑能不能做到一个$\log$。感觉这个做法还是比较厉害!考虑首先两边都只保留前$c$个数,这样问题变成求并的中位数。全局的中位数应该在两边的中位数之间(包含)。比较两边中位数的大小,如果左边的中位数比右边的小,那么左边比中位数还小的部分就没希望了,右边比中位数还大的部分就没希望了。从高到低比较每一位,问题是相同的时候怎么办,发现每有一位相同,两边中位数间的区间长度就减半,而全局中位数必然在这个区间里。把区间外的数贴到区间端点上不影响答案,所以我们每一步要么让值域减半要么砍掉一半的数。

R3

A. 整数

dp,设$dp(i,S)$表示从高到低考虑到第$i$位,$S$中的数还卡上限的方案数,转移枚举这一位每个数选啥。

考虑能不能法嘛塔之类的。如果$S$的第$k$位是$0$,那么可以随便选,如果$S$的第$k$位是$1$且这一位上界是$0$,那么只能选$0$,可以先处理完它的影响,如果这一位上界是$1$,那么这是一个and卷积。复杂度$O(2^nn\log v)$。

B. 举办乘凉州喵,举办乘凉州谢谢喵

数点大师。容易树分块,在收缩树上直接跑,做到$O(\sqrt{n})$。但是std是俩$\log$啊?

建个top tree先。不停分裂直到路径被分成若干个cluster path,在这个收缩树上跑类似的东西即可。预处理cluster内和一个界点出发和cluster path出发每个半径的答案,复杂度是一个$\log$。

C. 六元不定方程

这么猛。crt先,这大概就是为什么每个素因数次数都是$1$啦。考虑素数怎么做。

什么mo题。考虑枚举$a,a^\prime$,那么有$p$对$b,b^\prime$满足$ab+a^\prime b^\prime=r$,因为这是一条直线。继续考虑$c,c^\prime$的对数,这里有两条直线,它们可能没有交点,有一个交点,重合而有$p$个交点。有$0$不能比斜率,所以看起来要全靠叉积,容易知道$ab^\prime-a^\prime b=0$时不是一个交点,如果还有$a=b,a^\prime=b^\prime$就是重合,否则就是没有交点。那么我们先全当一个交点,然后减去$ab^\prime-a^\prime b=0$且不满足$a=b,a^\prime=b^\prime$的,再加上满足$a=b,a^\prime=b^\pirme$的。

可以感觉到$r=0$是需要特判的。当$r\neq 0$,$a,a^\prime$不能都为$0$。我们最后考虑$r=0$的情况。

考虑$a=b,a^\prime=b^\prime$。这就是$x^2+y^2=r$的对数,这他妈不是圆上整点计数吗。但是这里是模意义下的,所以不太一样啊。

首先特判掉$p=2$。考虑枚举$x$,那么如果$r-x^2$是二次剩余就有两个$y$,否则没有$y$。也就是说我们要算

\[\sum_{i=0}^{p-1}((r-i^2)^\frac{p-1}{2}+1)\]

这个式子,其实不是很好啊。考虑直接枚举$i^2$,这时候就有事可做了

\[\begin{aligned} &\sum_{i=0}^{p-1}(i^\frac{p-1}{2}+1)((r-i)^\frac{p-1}{2}+1)\\ =&\sum_{i=0}^{p-1}(i(r-i))^\frac{p-1}{2}+2\sum_{i=0}^{p-1}i^\frac{p-1}{2}+p\\ =&\sum_{i=1}^{p-1}(\frac{r}{i}-1)^\frac{p-1}{2}+2\sum_{i=0}^{p-1}i^\frac{p-1}{2}+p \end{aligned}\]

对前一个$\sum$所做的事情是提了两个$i$。膜奇素数恰有一半二次剩余,所以后一个$\sum$是$0$。

如果$r=0$,显然前一个$\sum$是$(p-1)(-1)^\frac{p-1}{2}$。否则$\frac{r}{i}-1$取遍$0,…,p-2$,只有$p-1$没有被算,所以它是$-(-1)^\frac{p-1}{2}$。

考虑$ab^\prime-a^\prime b=0$。这相当于$b=ka,b^\prime=ka^\prime$,那么我们枚举$k$,就变成$k(x^2+y^2)=r$的解数,也就是$(x^2+y^2)=\frac{r}{k}$的解数。这里$\frac{r}{k}$取遍$1,…,p-1$,所以我们只需要减去$x^2+y^2=0$的解数,刚才已经算过这个啦。

现在考虑$r=0$。此时上面的推导还是成立很多,但是可能有$a=a^\prime=0$或$b=b^\prime=0$的情况,此时就不是直线了。剩下的情况大概都是一样的。

R4

A. 【模板】线段树

考虑一个序列被整个反复操作会发生啥,经典地,操作$2^k$次是简单的,这会让前$2^k$个不变,剩下的$a_i\leftarrow a_i\operatorname{xor}a_{i-2^k}$。可以用lucas定理说明这件事,因为这就是膜$2$的二项式系数的递推式嘛。

见鬼的事情是这个标记和前面是啥是有关系的。这下想不分块都不行喽!并且这个题看起来就很像分块法法。

考虑我们把序列和时间一起画到平面上,不妨让序列当横轴吧,也就是说每行是一个时刻的序列。那么每个位置可能从下面转移来,或者从下面和左下转移来。时间分块,每一块里的修改和查询把列分成若干段,每一段中每行的情况是相同的,我们不妨把一个这样的东西称为一块。

所以考虑一块怎么做。我们需要也只能知道这一块左边和下边的值,要推出右边和上边的值。考虑左/下一个位置对右/上一个位置的贡献,发现贡献就是某个二项式系数膜$2$,非常好对吧,经典地lucas定理,然后可以用类似法嘛塔的dp做到$O(n\log n)$。这样总复杂度是$O(n\sqrt{n}\log n)$。

直接分块可以得到一个在线做法,但是常数会大一些。

B. 【模板】树链剖分

考虑对于两条链$x,y$,取什么链$t$可以让$x\cup t=y\cup t$。可以发现需要让$t$包含$x+y-x\cap y$,因为$x\cup t$需要包含$y\cup t$,那么$t$需要包含$y-x$,同理$t$也需要包含$x-y$。

$x+y-x\cap y=x\oplus y$。如果这个对称差不能被一条链覆盖,那就没救。否则,要么$x,y$共一个端点,要么$x,y$的并可以被一条链覆盖。

考虑前者。枚举这个端点,找到所有的链,要统计它们之间的贡献,那么两条链之间的贡献就是子树大小的乘积,容易$O(1)$算。需要特判同时满足并可以被一条链覆盖的情况,需要特判这个点有一条自己到自己的链,由于前者,需要在虚树上dfs,不过这里还是只需要虚树的dfs序。

考虑后者。这下我们不能枚举这条链了。考虑树是链怎么做,相当于$(a,b),(c,d)$的贡献是$\min(a,c)(n-\max(b,d))$。从右往左枚举$\min(a,c)$,让它是$a$好了,那么如果$\max(b,d)$是$b$,也就是说$(a,b)$包含$(c,d)$,是一个二维数点,如果$\max(b,d)$是$d$,可以用BiT维护$a<c$且$b<d$的链的数量。

那么考虑树怎么做,点分治,统计 覆盖$x,y$的并的最短的链 经过分治中心的答案。那么$x,y$要么经过分治中心,要么是某棵子树中的一条祖先-后代链。对于包含的情况,不妨认为是$x$包含$y$,那么$x$经过分治中心。对$y$是否经过分治中心的两棵不同子树讨论,如果是,是一个二维数点,这里给每个子树对都开一个离散化二维数点,总元素数不超过链的个数。否则,$y$只有更深的端点有用,扫扫即可。对于不交的情况,如果两条链都不经过分治中心,直接乘一乘。不妨认为是$x$经过分治中心,那么就是算完全包含在子树中的$y$的数量,只有更浅的端点有用。

还剩下相交但不包含的情况。两条链不可能都不经过分治中心。如果只有一条经过,还是不妨认为是$x$,那么$y$相当于一个链加,然后拿$x$的端点去求和。如果两条都经过,那么相当于求有多少条链,一个端点在$x$一个端点的子树中,另一个端点在$x$另一个端点到分治中心的链上,扫后者,满足后者的$y$就是一个到分治中心的链加,使用静态lct可以做到$O(n\log n)$。

每条链一旦经过分治中心,就不需要再递归下去了,所以复杂度是$O(n\log n)$。如果懒得静态lct,树剖线段树就是$O(n\log^2 n)$。但是你甚至要写这个题了,还有啥好懒的?

据说有简单主席树做法。

C. 【模板】双端队列

xviii open cup gp of romania L. Xormites

让我们想起 termites。但是这里只需要判断大小。

经典地,如果$n$是偶数,黑白染色,那么先手总可以选择一个颜色取走,因为轮到他的时候两边总是包含所有两种颜色。所以要么先手胜要么平局。如果平局,说明全局xor和是$0$,那么无论如何都平局了,同样,如果全局xor和不是$0$,那么不可能平局。

如果$n$是奇数,轮到后手的时候两边总是包含所有两种颜色,但是后手不能把黑色全取走,因为先手比他多取一个,上来必然会取一个黑色。

一个想法是,考虑如果他取的黑色是$t$,剩下的黑色xor和是$x$,白色是$y$,那么如果$x>y\operatorname{xor}t$或$y>x\operatorname{xor}t$那么后手就赢了,否则还不一定发生什么。但是这个想法看起来,比如$x=y$的时候好像就没救啊!

换个想法,考虑全局xor和的highbit,两个人必然在这里拿到的不同,在高位必然拿到的相同,也就是说其实只有这一位有用,谁拿到奇数个$1$谁就赢了。然后我们就会$n^2$ dp啦!

考虑怎么快一点啊。petr说的好,接下来先手必须和后手拿到相同的数,否则必然有一个颜色剩下奇数个$1$,先手就输了。打表可以发现,先手胜当且仅当序列满足,$1$的个数是$4$的倍数,并且它可以表示成$ABA^R$,其中$B$的每两位相同。于是就结束了。

R5

A. 在路上

眼熟的。

奇数是为了保证重心唯一。

考虑重心满足啥,好像没啥可用的东西啊?

考虑如果树是一条链,我们可以找到一端,然后$O(n\log n)$地排序,找到一端只需要按任意顺序扫,维护目前最靠边的两个点。

如果随机找一条链,那么有很大的概率它是经过重心的,因为端点在重心同一棵子树的概率不超过$\frac{1}{2}$。

现在有一条链,可以$\log n$地在链上二分得到它挂在哪个点上。求出了每个点所挂子树大小,如果重心在链上,只可能在链的带权中点的位置。

为了确定它是不是重心,我们只需要看挂在它上的点分别挂在哪颗子树。查两个点和候选的重心,那么它们在不同子树当且仅当答案是重心。

继续随机,每次随一个点,把它所在的子树找出来。如果随机了$\log$次还没有找到一棵大小$>\frac{n}{2}$的子树,或者剩下的部分已经$<\frac{n}{2}$了,就可以停下。复杂度$O(n\log p)$,这里$p$是正确率。

分析一下常数,随机一条链是$n$,设链长$l$,在链上排序是$l\lg l$,二分是$(n-l)\lg l$,加起来就算作$n\lg n$吧。剩下的部分,找到大小$>\frac{n}{2}$的子树期望只需要$O(1)$轮,那么也就是说只会付出一次$n\lg n$。也就是说失败的一轮是$n\lg n$,期望失败两次,成功的一轮需要$n\lg n+\lg p$。好像有不少分。

感觉这已经是$\lg$的极限了。考虑怎么线性。

注意到我们只需要中点,考虑类似于线性kth的二分,二分之后可以线性地check,并把不包含答案的那部分砍去。但是二分不一定是平衡的,而我们砍去的是小的一半。考虑随机一个点,二分出它挂在链上哪个点,这样就平衡了。

但是二分需要排序。发现爆力找是不需要排序的,那么一边递归一边找到那部分包含哪些点即可。

判定重心是找绝对众数,可以做摩尔投票。

B. 心跳排列图

先做 心跳 和 排列图。非常好对吧!

洛谷8554 心跳

考虑如何判定。发现去掉一个不是前缀$\max$的数啥也不会发生,去掉一个是前缀$\max$的数,会让后面一些数露出来。

考虑如果我们知道了前缀$\max$一开始有$k$个,那么所有前缀$\max$数量变化的位置必然都是前缀$\max$,而变化了$d$就说明接下来这一段有$d+1$个数要露出来。这里排列和实数是等价的,所以我们很容易构造,除非这一段长度不到$d+1$,或者是删掉了第一个元素而没有数露出来。

但是我们不知道前缀$\max$有多少个啊。考虑因为段太短才会无解,我们直接让全局$\min+1$作为一开始的前缀$\max$个数。然后就可以dp了,枚举这个全局$\min$,设$dp(i,0/1)$表示上一个选了$i$,没有/有一个全局$\min$出现过即可。前缀和优化,复杂度$O(n^2)$。

更劲爆的事情是,每个$a$只有一个初始前缀$\max$个数合法,可以看看ei的证明。所以只需要枚举它了。然后答案甚至可以整式递推,不过这里好像跟它关系不大。

cf1696 D. Permutation Graph

怎么他妈才1900啊?

单调栈,也就是说我们要向单调栈的一个前缀连边,可持久化线段树优化建图即可。

但是这个多少有点菜了!猜测其实只有$O(n)$条边,不过这肯定不对,比如$1,…,n$就有$n^2$条边。

猜测我们其实不会往回走。如果有$i,j,k,l$依次排列,我们走了$i,k,j,l$,那么画一画可以发现其实必然可以从$i$走到$l$。所以只需要线段树优化dp。

但是还要再智障一点,转移只可能是在递增或递减单调栈上尽可能走,因为相邻两步如果都是从$\min$走到$\max$则可以合并,否则画一画可以发现走的远必然不劣,所以只需要枚举第一步走的啥,在单调栈上不停二分,连dp都不用喽。

也不用二分,可以直接爆力找。

甚至不需要枚举,因为前两个数的大小关系让你只有一种可能的走法。

好了我们回来看心跳排列图。这玩意真的能做?

考虑我们删了一个数会发生啥,如果它不在最短路上,那么啥也没发生,否则考虑正反同时贪心也可以拼出答案,所以枚举两边第一步的奇偶性,一共有四种可能对吧。固定一种奇偶性的话这个看起来确实和 心跳 一样非常局部。

注意到前两个数的大小关系确定了第一步走啥。最短路长度的奇偶性确定了最后一步走啥。

不妨认为删掉的地方是一个谷。如果最短路长度要增加$k$,如果$k$是偶数那好说,但是奇数不太好说,不过可以感觉到如果长度的奇偶性改变,删的必然是$1,2,n-1,n$中的一个,因为最前/最后两个数的大小关系就确定了那一步走啥。需要注意如果$k=-2$,那么我们删了之后,前后两个变得可以一步走到了,此时这一步和上下两步中某一个必然可以合并,这就产生一个$-2$。

所以看起来就比较阳间了!具体考虑咋构造啊。如果要把这一段填满,只需要放上下上下这样的即可。如果要一步走到,只需要全塞在中间即可。前一种放$\frac{k}{2}+1$对,剩下的后一种填满即可。

但是还有删倒数第二个数的问题。比如说最后一步本来是上升的,现在变成了下降的,说明$a_{n-1}<a_n,a_{n-2}>a_n$。感觉前面的构造在这里没啥问题啊(

可能的初始最短路长度只有$\min,\min+1,\min+2$。枚举即可。

但是看一看官方题解,发现还有一堆奇怪情况需要讨论。多少有点不太清真了。

C. 核

见 线性代数。

R6

A. 硬币游戏

先做ccpc20 final H. Nonsense。收录于 数数从入门到直僵僵地镶嵌在门框里。

然后我们回来看这个题。考虑先随便操作,然后容斥掉$2i-1,2i$次操作了同一个的情况,这里操作两次相当于没操作所以非常好对吧,对所有$k$求出答案后容易法法做到$O(n\log n)$。yny好像给zroi也出了一个这么容斥的。是不是间接导致我在sdptt场切了whq的某个lgv题,咍咍。

考虑计算$F(a,b)$,如果随便操作咋做,考虑枚举$p$,操作奇数次的egf是$O=\frac{e^z-e^{-z}}{2}$,偶数$E$类似,我们得到

\[\sum_{p=a}^{n-b}\binom{p}{a}O^aE^{p-a}\binom{n-p}{b}O^bE^{n-p-b}=O^{a+b}E^{-(a+b)}h_a\sum_{p=a}^{n-b}\binom{p}{a}a^p\binom{n-p}{b}b^{n-p}\]

右边就是Nonsense。但是Nonsense只有同时跟$a,b$相关的整式递推,这里希望找一个只和$a$相关的,但是不太能找啊,不过关系不大,仍然可以直接写出gf然后法法。不妨假设我们算出它了,把它乘进$h_a$里,毕竟$h_a$是随意的嘛。接下来从$0$到$a$求和

\[\sum_{i=0}^aO^{i+b}E^{-(i+b)}h_i=O^bE^{-b}\sum_{i=0}^aO^iE^{-i}h_i\]

换元$t=e^z$,然后就可以直接分治了,也就是分别递归左右,把右边$+1$再乘上左边,往上传。复杂度$O(n\log^2 n)$。

B. Y 君的序列

看起来好劲爆。

容易想到每次交换两个数。

首先我们需要一个牛逼观察,如果$x+y$是奇数,那么操作$x,y$,在$\bmod{x+y}$下相当于把$x,y$变成$\frac{x}{2},\frac{y}{2}$,证明考虑$x=-y\pmod{x+y}$。也就是说操作两个和为奇数的数是可逆的。

考虑什么情况下我们可以变成$y,x$,那么如果$y$是奇数,操作了$k$次,也就是$\frac{x}{y}=2^k$这样的。因为$x=-y$,也就是$-1=2^k$,也就是说膜$x+y$下$2$的幂包含$-1$则必然可以。

考虑一个简单情况,如果$x+y=2^k+1$,那么$2^k=-1$。用这种情况就够了,我们依次归位$n,…,1$,考虑如何把一个数和$1$交换,如果会了这个我们把$n$目标位置的数和$1$交换,再把$n$和$1$交换即可。我们每次找到最小的$k$满足$n<2^k+1$,那么取$y=2^k+1-n$,把$n$和$y$交换。容易发现每次操作后$k$必然减小,所以操作次数是$O(n\log^2 n)$。

C. >.<

爆力怎么做?注意到匹配的部分,最长的的信息量足够给出所有短的,所以只需要记最长的即可。当最长的失配的时候,找到它这个前缀的一个 是别的路径的前缀 的后缀作为新的最长的。同时最长的的最后一位就是我们所在的点对吧。

考虑建个acam,呃呃,直接在此基础上建个dfa,主席树把acam的转移全部求出来,然后每个点连到出边指向的所有点。这里状态数是对的但是边数不对,如果一个点在串中出现很多次又度数很大我们就死了。不过关系不大,可以注意到$u$的转移和$\mathrm{fail}(u)$的转移是几乎一样的,而这俩串的末尾都是$u$,也就是说出边也是一样的,那么其实所有点和fail不同的更新数量是线性的。对每个图上的点主席树优化建图即可。主席树上都是$0$边,所以复杂度是$O(n\log n)$。

R7

A. foo~

先考虑序列怎么做。从左往右dp,如果是后缀$\max$个数大家就都会了。我们可以把两种分别转移一遍,如果是前缀$\max$,那么每次是一个后缀的贡献$+1$,然后这个后缀接下来的贡献方式都是一样的了,并查集合并一下,全局开一个堆即可。当然这里只有$+1$,开桶即可。

考虑环怎么做。不会捏。不过注意到$k$非常小。但是这他妈好像是个坏事啊?

我们先考虑$k=1$咋做,直接复制一倍单调栈就好了。

考虑换个想法。注意到前缀$\max$个数就是卡笛尔树左链长度,后缀$\max$个数就是右链长度,这虽然没有告诉我们什么,但是至少告诉我们以区间的$\max$为界,前缀$\max$都在左边,后缀$\max$都在右边。考虑钦点出所有的区间$\max$,然后每一段选一个前缀贡献后缀$\max$个数,对应的后缀贡献前缀$\max$个数,这样我们知道全局$\max$必然被选。但是因为是取$\max$,这里要记上一段那个后缀的贡献,看起来比较爆炸。

但是感觉上全局$\max$还是很有用的。感觉我比较shaber,我们从全局$\max$出发看选择哪一侧,那么另一侧相当于不用必须走到最后,于是可以从全局$\max$出发dp,特殊处理第一段即可。

B. 卑鄙的下毒人

一眼对偶。

C. 回文

这他妈啥。这下想不分块都不行喽。注意到是回文后缀当且仅当是最长回文后缀的border,所以其实我们求出最长回文后缀的border结构即可。

考虑直接维护这玩意。发现它看起来居然有点好合并,因为回文后缀这玩意,合并的时候,完全包含在右边的是简单的,跨过中线的,如果中心不在中线上则必然包含左侧的回文后缀或右侧的回文前缀,否则这个串是确定的。

考虑如果包含右侧的回文前缀咋做,我们设一个等差数列是$a,ab,…,ab^k$,长度为$1$则特判,设右侧整个是$ab^kc$,那么每一项分别要求左侧的后缀是$c^T,c^Tb^T,c^T(b^T)^2,…$。可以注意到所有形如$ab^k$的都是回文串,因为归纳一下,它倒过来等于$b^T(ab^{k-1})^T=b^Tab^{k-1}$,那么根据归纳假设$ab^{k-2}$是回文串。也就是说这里$b$不能是$c$的前缀。那么如果$c$不是$b$的前缀,也就是说$c^T$不是$b^T$的后缀,那么只有第一个可能满足,否则我们就是要求从中间和中间往左能连续匹配多少次$b^T$,再看最后一次能不能再匹配一个$c^T$,倍增即可做到$O(\log n)$。因为每个border的长度都比上一个大,所以这里倍增的总复杂度其实是$O(\log n)$的。

继续考虑包含左侧的回文后缀的情况,如法炮制,我们设一个等差数列是$a,ba,…,b^ka$,左侧整个是$cb^ka$,那么相当于在$c$里每隔$\vert b\vert$匹配一个右侧,那么$\vert b\vert$就是一个周期,二分出它最长扩展到哪,转化成border可以用一次hash判断它是不是周期,再看看循环节到底是不是右侧即可。

所以我们会了$O(\log^2 n)$次hash的合并,数据结构维护hash即可,看起来这里根号平衡比较快。

R8

A. 环覆盖

看起来 可环覆盖 是简单的,它就是有欧拉回路嘛。

所以这就是一个线性代数问题了,我们要选$k$个向量xor起来为$0$。让我们回忆一下选任意个向量xor起来为$0$的方案数咋做,好像就是跑个线性基,然后线性基外随便选,基总能把它调成$0$。但是这里不太一样了,基外随便选的话,基内选的个数我们是不知道的,不过关系也不大,外面有最多$2^{n-1}$种情况,可以再跑个线性基来枚举这些情况,然后看基里面选多少条边即可。

好像官方题解要正交补,感觉没太有必要。

B. 妙妙题

这么难???

看起来我们猜对一半就是满分了。怎么样才能猜对一半呢,看起来这大概是个经典问题,如果知道位置,我们让一半人猜一共有奇数个1,另一半猜一共有偶数个1就行了。

如果不知道位置,多少有点见鬼了。感觉比较震撼,考虑把所有人安排在单位圆上,然后画一条经过原点的直线,一侧的人猜一共有奇数个1,另一侧猜一共有偶数个。设第$i$个人位于$e_i$,那么取$\sum b_ie_i$作为这条直线的方向,叉积的时候恰好可以消掉位置的影响,这就是向量带给我的骄傲的资本。

问题是$\sum b_ie_i$可能是$0$,那么我们知道它必然由若干个对称的部分组成,此时如果一个人破坏了这个对称,他的$b$必然是$1$,而此时所有人的叉积都是$0$,在上面的case中则可以把算出$0$的人直接扔掉,所以我们让算出$0$的人根据剩下的$\sum b_ie_i$是不是$0$来猜就好了。

我他妈刚知道gyr是最佳女选手。这不给cdq露一手?

C. 大冬天题

也就是求一个最大匹配对吧。但是$10^{100}$有点太极端了!

感觉比较离奇。注意到如果两个奇数差是$2$的幂,那么它们必然互素,因为除了$2$,没有一个素数整除$2$的幂。所以我们不停取最大的$2$的幂去剥即可,这必然可以得到一个完美匹配。

R9

A. 森林游戏

这不是我们核仁的题目吗。

让人不得不想起termites。猜测我们最后会把所有情况都转化成特殊性质A。

termites给出了链的做法。注意到如果有若干条链,大家必然都贪心选择最大的那个,所以其实它们相当于一条链。如此自底向上归并,对每棵子树,加入根之后不停对第二位的数用termites的做法即可。问题在于归并,splay启发式合并即可。

B. 会议

考虑怎么获得很多分,看起来我们需要严格$O(1)$,考虑只插入怎么做,大家都会对吧,呃好像也不完全会,因为我们还要统计这个数出现了多少次。删除其实是简单的,维护所有的匹配,删的时候重插匹配的那个数即可,这样我们会了10%。如果插入一个数的时候,绝对众数的候选切换了,那么我们,看起来是需要维护所有数的出现次数的,因为所有数都可能快速成为绝对众数候选嘛。

考虑我们找到一对不包含新的绝对众数候选的匹配,如果找不到那就说明它确实是绝对众数,否则说明它确实不是绝对众数,然后如果有了两个候选,我们跟这对匹配进行交叉,变得没有候选。这样我们只操作匹配并且变化量严格$O(1)$了。那么问题就是我们怎么找到这么一对。一个均摊的做法是直接爆力找,如果发现相等就标记某个元素的颜色,直接并查集维护出现过的所有相等关系,在爆力找的时候跳过这些必然相等的对。这样确实是平均每个元素两次。

那么考虑做一些scheduling,感觉这个东西就很对了啊。

但是题解看起来和它没有任何关系。建议自行阅读题解。

C. 小 H 分糖果

显然贪心选最大的去$-1$,如此$m$次。那么二分就好了,问题是查$>k$的数$-k$的和,也就是它们的个数和和对吧,静态lct,每个点开个线段树即可。也可以不用静态lct,直接差分之后在dfs序上做即可。

R10

A. 九王唱

考虑如果只剩下一个人,他显然选择他认为最大的那首歌。

如果剩下两个人,第一个人会考虑第二个人的排序,他可以控制答案是第二个人认为最大的还是次大的,但是总不能是最小的。

注意到第二个人认为最小的肯定不会留下来,即使第一个人想要留下它。那么在这两个物品中第一个人就会扔掉他认为最小的。

对于任意多人的情况,最后一个人认为最小的肯定不会留下来,除了这个以外,倒数第二个人认为最小的也不会留下来,所以相当于所有人倒着依次扔掉自己认为最小的。直接做是$O(n^3)$。

考虑shift一位有什么变化,我们还是别看成循环移位,看成滑动窗口吧。那么让最后删掉一个人,开头加上一个人,此时多了一个东西向前流通,我们向前爆力找到它何时成为最小的,然后把那个人本来拿走的替出继续向前找,这样单次复杂度$O(n)$。

B. 千百

参考资料

改编自一道校内模拟赛题。

这不是我们ctt2019 D3 B. 数圈吗。这他妈也叫校内???

如果$n$是奇数,那么必然无解。如果$n$是偶数,我们把$i$乘上$(-1)^i$,就转化为数圈。

让我们回忆一下数圈怎么做吧!总和$<0$必然无解,总和$=0$的话,注意到操作是可逆的,所以要么不需要操作要么无解。现在总和$d>0$,我们把环展开成双向无限长的序列,并从$0$开始做无限长的前缀和,这个前缀和只需满足$s_i=s_{i-1}+a_i$所以是有定义的,此时一次操作相当于每隔$n$个数交换相邻两个数。那么我们要把它变成递增的,就是要让逆序对数变成$0$,但是逆序对数显然是无限的,考虑一个别的东西,设$c_i$表示$i$后面比$i$小的数的个数,由于总和$d>0$这个是有定义的,那么我们就是要把所有$c$变成$0$,而每次操作恰好可以让所有膜$n$为某个数位置上的$c$减少$1$或增加$1$,所以就是求$c_0+…+c_{n-1}$。那么枚举两个数$0\leq i,j<n$,考虑$i$对$c_j$的贡献,也就是$\max(\lceil\frac{s_i-s_j}{d}\rceil-[i<j],0)$,也就是说每一圈会让差减少$d$,减到$0$就没有贡献了。$-[i<j]$是因为如果$i<j$的话会在这一圈多贡献一次需要减掉。

那么我们需要化一化,这个和$0$取$\max$相当于判断是否有$s_i>s_j$,如果有则左边$\geq 0$,如果没有则$\leq 0$。然后把$s_i$拆成$q_id+r_i$,其中$r_i=s_i\bmod{d}$,那么贡献变为要求$s_i>s_j$的$q_i-q_j+\lceil\frac{r_i-r_j}{d}\rceil-[i<j]$,中间那一项相当于$[r_i>r_j]$,所以是一个一维数点两个二维数点,复杂度$O(n\log n)$。

那么我们回来看这个题,每次给相邻两个数$+v$,在我们奇数位取负之后它是不改变$d$的,做前缀和之后相当于修改了一个$s$。这里要求每个数都$>0$,那么也就是改成$\lceil\frac{s_i-s_j+1}{d}\rceil$,看起来没有本质区别。那么只修改一个$s$,我们就删去关于它的贡献然后加上新的,按$s$之外的那一维扫,在前后缀BiT上各再查一次即可求出变化量。复杂度$O(n\log n)$。

C. 小 P 爱学习

看起来有点极端了。先考虑一个多项式复杂度的做法,把和的乘积拆开,也就是在每组各选一个乘起来。考虑$m=1$咋做,dp,设$dp(i,j,k)$表示前$i$个,分出了$j$个非空的组,其中$k$组已经选了一个的答案,转移决策加入一个新的组还是加入一个已有的组,以及这个数选还是不选,复杂度$O(n^3)$。

这玩意怎么优化啊?考虑别分组了,我们直接钦点一些元素作为每组中选的,把剩下的用斯特林数分到这些里面,复杂度$O(n^2)$。

对于$m>1$的情况,还是钦点一些元素作为每组中选的,dp的复杂度是$O(n^2m)$。那么如果我们钦点了$c$个,就要把剩下的分成$c$个大小为$km-1$的组,可以看到这里不可能有非空的组了。那么考虑用egf描述这玩意,它等价于给每个元素分配一个数,每个数出现$km-1$次对吧,所以每个数就是$F=\sum\limits_i \frac{z^{im-1}}{(im-1)!}$,然后要算$[z^{nm-c}]F^c$。

那么首先把$\frac{1}{z}$提出来,重设$F=\sum\limits_i \frac{z^{im}}{(im-1)!}$,此时我们要提取$[z^{nm}]$,那么就可以把$z^m$换掉了,也就是说它等于$[z^n]\left(\sum\limits_i \frac{z^i}{(im-1)!}\right)^c$。爆力卷积是单次$O(n^2)$的,我们要卷$n$次,复杂度就是$O(n^3)$。

注意到这里只求一项,考虑折半,爆力算出$1,…,\sqrt{n}$次幂和$\sqrt{n},2\sqrt{n},…$次幂,然后就可以$O(n)$地求一个了,复杂度$O(n^2(m+\sqrt{n}))$。

R11

A. 第一代图灵机

这他妈啥啊。考虑静态问题咋做,每个颜色相当于ban一个左上2-side矩形,然后每个前缀和相当于行加列加,感觉删除不好做啊,考虑插入咋做,我们直接维护左上轮廓线上每个拐点的答案,那么每次查询可以二分出轮廓线上的情况,只有两个端点处需要remake一下。

但是注意到他妈数都是正的,那我remake个锤子呢。也就是说答案就是每个拐点处的答案的$\max$,所以问题只剩维护轮廓线了。

看看有没有什么维护轮廓线的经典方法,它其实是单调栈对吧,那么我们使用类楼房重建线段树即可。但是题解好像跟我不太一样。

B. 朝圣道

可以猜测答案是整式递推的,考虑一些gf方法,问题是我们怎么只算正的,别只算正的了,只算负的吧,求导之后乘上$\frac{1}{1-z}$然后提取$[z^0]$即可。

那么可以发现转移$F=\frac{1}{4}z^{-1}+\frac{1}{2}+\frac{1}{4}z$的一个简单形式是$\frac{(1+z)^2}{4z}$,它$n$次再求导就是$n\frac{(1+z)^{2n-2}}{(4z)^{n-1}}(\frac{2(1+z)}{4z}-\frac{(1+z)^2}{4z^2})$,后面通分一下是$\frac{(1+z)^2}{4z^2}$,然后我们就是要算$\frac{n}{4^n}[z^0]\frac{(1+z)^{2n}}{z^n}=\frac{n}{4^n}z^n^{2n}=\frac{n}{4^n}\binom{2n}{n}$,所以答案确实是整式递推的。然后直接任意膜数lucas啦。

C. 卡牌游戏

这他妈啥。可以看到那个东西就是$S-S\bmod{\mathrm{lcm}(b_i,b_{i+1})}$,这样略微阳间了一点。

事已至此,先dp吧。如果$\mathrm{lcm}$很大,那相当于啥也没有。也就是说超过$S$的$\mathrm{lcm}$我们大概是不会选的,而可以看到$S$很小。

那么大家都知道$\mathrm{lcm}(a,b)=\frac{ab}{\gcd(a,b)}$,给每个位置记上$S-S\bmod{\mathrm{lcm}(b_i,b_{i+1})}$,然后枚举$\mathrm{lcm}$,可以过随机的点。

那么考虑根号分治,如果$a_i$很大就枚举$\mathrm{lcm}$,如果$a_i$很小,就直接枚举$a_i$,复杂度$O(n\sqrt{S})$。这里还要拼前后缀,但是好像不是很会拼。

看起来需要一些$S-S\bmod{\mathrm{lcm}(b_i,b_{i+1})}$的性质,但是感觉没啥好性质啊。不过可以注意到如果我们取根号分治阈值在$\frac{\sqrt{S}}{\sqrt{2}}$左右,那么选小的数看起来非常优秀,因为你可以得到至少$\frac{1}{2}S$,那么如果有至少三个小数我们就必然会选。所以拼前后缀的时候,两边最多有三个没选的小数,也就是说只有$O(1)$种情况,这里每次拼接$O(\sqrt{n})$的。同时也不需要单独维护小数了,因为我们只会往前转移至多三个。复杂度$O(n\sqrt{S})$。

R12

A. 回文匹配

让我先做一下 太阳神的宴会。看起来那个题比这个要简单一点。

先考虑$q=1$。两个串回文匹配当且仅当manacher的结果相同对吧。那么可以注意到区间manacher的结果就是把每个数对左右端点bound一下。但是这个有点困难。

考虑一个能简单地向一侧扩展的东西,这样我们只需要处理另一侧了,可以建dfa了。考虑每个位置结尾的最长回文后缀长度,这个相同等价于回文匹配,证明考虑根据最长回文后缀长度我们可以得到pam的结构,并且可以在pam上找到每个回文串的endpos,这样就得到了manacher。最长回文后缀看起来非常好求,即使是在$T=1$的时候,因为我们有多串pam。

怎么建dfa呢。类似于kmp地做就好了。这是个等价关系,也就是说如果区间$[l,r]$匹配了$s$,$s$有回文匹配下的border $b$,那么$[r-\vert b\vert+1,r]$也匹配$b$,而且前缀$b$的信息量是很足的。而右边加字符的话,只需要查询被一个区间bound住的最长回文后缀,直接在pam上跳即可。这里爆力跳好像是有均摊的,但是我们一会会用到严格的做法,倍增地跳即可。

所以$T=0$就是直接对所有最长回文后缀序列建这种acam。建出来之后只需要对每个$t$做,dfs序BiT即可。这里acam只需要fail而不需要求出转移,因为我们只是在跑匹配啊。

考虑$T=1$,对trie求每个点的最长回文后缀是简单的。这里我们需要求出整个dfa,因为是在trie上一边dfs一边匹配,失配没有均摊了。那么我们考虑$O(n\Sigma)$的做法,这里我们枚举了$t$,$t$匹配到代表串$u$的点,那么$t$往后加某个字符,必然对应于$u$加了某个字符,也就是说一共只有$O(n\Sigma)$个转移,而为了求出这个对应,只要求出最长回文后缀长度就行了,这个还是一边dfs一边维护pam,在pam上倍增即可。然后为了求出这些转移,需要从fail那里继承对吧,故技重施,发现fail往后加某个字符也对应于$u$加了某个字符,还是只需要求出最长回文后缀长度就行了,这说明什么 kmp就是自己匹配自己 这样的说法还是有些意义的。使用hash table,复杂度$O(n(\Sigma+\log n))$。

这谁想的到啊?

B. 魔术师

投降。

C. 树与染色!

其实就是同色连通块大小。这不是我们qtree的问题吗?

哦原来是子树推平。连续段均摊一下即可。

但是怎么1e6啊。考虑lct是咋做的,子树推平的时候可能会和父亲分裂,然后可以爆力找到子树中不存在的边进行合并,这里需要知道父亲的颜色,dfs序线段树一下就好了。更进一步地,发现一个连通块最高的点被推平的时候,整个连通块都会被推平,而如果最高的点没有被推平,这个连通块就一直存在。所以我们可以只用dfs序线段树维护每个连通块最高的点,推的时候就是查询子树中的最高的点把它们删掉,那么怎么算连通块大小呢,产生一个新的连通块的时候,会让它上面那个连通块的大小减少一些,也只有它的大小变化了,这里也不需要静态lct,还是dfs序线段树,因为这个上面的连通块的最高的点必然是到根的链上最晚出现的最高的点,所以只需要支持区间推平单点查询,或者说我们其实在维护每个点属于哪个连通块。复杂度$O(n\log n)$。

R13

A. 夹娃娃

$a$很大,所以其实没啥用,全乘起来即可,这部分可以爆力乘,爆力求逆,复杂度$O(nm^2)$。剩下的问题,也就是说有一堆gf,我们每次选一些截掉前$k$个,然后乘起来并乘上$\frac{1}{1-z}$,提取$z^m$。直接做是$O(qnm^2)$,这就是寄了,但是我们会$\ln-\exp$对吧,先预处理每种截取的$\ln$,这是$O(nm^2\log m)$,查询的时候加起来$\exp$,这是$O(qm(n+\log m))$。

那么怎么膜1e9+7呢。既然爆力是多项式复杂度,$n$很小是明示你爆搜预处理。注意到每次查询只有一个$k$,我们对每个子集预处理乘起来的结果,然后对有限制和没限制的分开,这样查询部分是$O(qm)$的。至于预处理,需要先枚举一个$k$,一共是$O(2^nm)$次长$m$的乘法,这就是寄了。$\ln-\exp$并不能改善什么。

发现我是shaber,并不需要把有限制的和没限制的分开,直接放一块就行了啊,所以说这处理出来的甚至直接是答案。那么自然考虑嗯折半,我们只要算$O(2^\frac{n}{2}m)$次长$m$的乘法了,但是还是不行。

注意到popcnt很大的时候$k$不能太大,我们可以统计一下状态数

\[\sum_c\frac{m}{c}\binom{n}{c}=\sum_c\frac{m}{c}\binom{n+1}{c+1}\frac{c+1}{n+1}\approx \frac{m}{n}2^{n+1}\]

所以其实我们是除了一个$n$的。复杂度$O(\frac{2^\frac{n}{2}m^3}{n})$。

看一眼题解。这他妈是啥?

B. 加速度

注意到如果我们跑的太快要撞到一个$r$了,但是希望保持足够的速度,最好的方法是在上一次减速的地方等一会,然后一直加$a$冲过去。容易发现这真的是最好的,因为反正时间被$r$给bound住了,这个就是能得到最大速度的方法。

所以直接在发生了减速的关键点间dp即可,这些关键点都是受$l$ bound住的所以时间是确定的。转移决策速度有没有减到$0$,如果到了的话等了多长时间,中间的复杂度$O(n^2)$。

C. 理论出线

考虑第一问怎么做,直接贪心地让所有$<v$的选手中最早离开的赢。

那么我们要造一个dfa来识别这个可行的选手集合对吧,但是这里直接dp比较好看。dp,设$dp(i)$表示前$i$个,$i$被选为$>v$的,选的个数的最小值和方案数。转移向后模拟看能走到哪,复杂度$O(n^2)$。

显然能走到的地方是一个前缀,但是我们好像并不是很会找到这个前缀。显然它是单调的,所以直接分治即可。并且dp值也是单调的,先拿堆跑一遍算出dp值,然后能贡献给最优解的转移就是一个区间,再线段树即可。

Bonus: 区间不单调。那么贪心仍然是正确的,不过我们要改成区间dp了。

R14

A. 做你妈

B. 染色

相当于每次决策把这个改成和下个相同,还是把下个改成和这个相同,然后走一步。

考虑了差分,但是好像有点困难。

看起来需要一些性质啊。考虑如何才能节省一步,如果两个格子颜色相同,那么我们把中间的改成和它们都相同的就能节省一步了。所以变成了类似于有若干个区间,选出尽可能多的不交的这样的东西,这里如果两个区间交为$1$可以都选。那么当然贪心选择右端点最左的,倍增即可。

甚至可以线性,考虑如果一个区间被另一个包含,后者必然不优,现在所有区间互不包含了。我们给每个区间连向选的下一个,得到一棵内向树,问题是求第一个$>r$的祖先的深度。接下来咋做啊?

C. 青蛙思直线

大家都是线性变换。需要推导一下对称的对称其实是啥之类的。懒了。

R15

A. 翻修道路

考虑只查一次怎么做。好像比较困难。

考虑只有一个省会怎么做。分层图即可。

考虑两个省会怎么做。显然$k$条的答案并不一定包含$k-1$条的。

不知道干什么的时候你就对偶一下!二分答案$k$先,那么看起来是每条边分配一个$c_{i,j}$,每个点分配最短路$d_i$,要满足$c_{i,j}\leq 1,d_j-d_i-(a_{i,j}-b_{i,j})c_{i,j}\leq -a_{i,j},d_i\leq k$,最小化$\sum c_{i,j}$。显然它不是全幺模的,这就是寄了。

靠,没看到$k\leq 8$啊。那我们就想起斯坦呐树,斯坦呐树的做法是直接对mst进行dp,那我们直接对最短路树进行dp,设$dp(u,i,S)$表示$u$为根,用了$i$条边,到达$S$中的点的答案,转移在这个点把几棵树接起来,或者接上一条边。注意到这里不需要不交并,只需要并,因为一个点算两次是必然不优的。但是$\max$没有逆,这就是寄了。复杂度$O(3^knm)$。

B. 多控制反转

这么难???

评价为少造量子计算机。

C. 摩斯电码 2.0

显然第一堆和最后一堆都投给$1$,所以这是个链。那么$v_1$就确定了。

二分答案$s$,那么一个政党$i$的至少的席位数就是最大的$s^\prime$满足$\frac{v_i}{s^\prime+1}>\frac{v_1}{s+1}$,也就是$s^\prime=\max(0,\lceil\frac{v_i(s+1)}{v_1}\rceil-2)$。现在要最小化这些东西的和,如果它$\leq m$那就可以。那么也就是说我们可以每次选择给一个加$s+1$,每当跨过$v_1$答案就$+1$。

所以先约掉$\gcd$(起点直接除$\gcd$上取整),现在所有环都是完全同构的了。考虑如果每次都可以随便选哪个怎么做,我们设环长是$l$,每次走$s$,那么考虑大概是怎么一个过程,我们会走$l$步回到起点,每一轮会走若干没有代价的和一个有代价的,总个数要么是$\lfloor\frac{l}{s}\rfloor$要么是$\lceil\frac{l}{s}\rceil$。那么有$\lceil\frac{l}{s}\rceil$的时候先走必然不劣对吧,如果没有的话,看起来比较见鬼。

是不是要用这个局部的性质了。开始dp,设$dp(i,j)$表示前$i$个,第$i$个走到了$j$的答案,那么我们考虑$i,i+1$之间那个分给$i$多少即可。$a$超过$2l$的话可以直接减去$l$,所以复杂度$O(nv\log m)$。

遗憾的是$m,v,a$都很大,看起来比较没救。考虑

usaco

我居然以为usaco是每个月都有。

从14~15赛季开始,usaco每赛季有四轮,比如22~23赛季有22 Dec. 23 Jan. 23 Feb. 和Open。这里只做Au和Pt。

18~19

Dec.

Au

A. Fine Dining

也就是说要对于每个$i$,找一个关键点$j$满足$\operatorname{dist}(i,j)+\operatorname{dist}(j,1)\leq\operatorname{dist}(i,1)+y_j$。

试一试发现$\operatorname{dist}(i,1)$是重要的,如果不是这个而是啥给定的东西,那就不太能做了。而由于$y_j$的存在,$\operatorname{dist}(j,1)$是不重要的,可以把它放进$y_j$里面去。也就是说我们可以写成$\operatorname{dist}(i,j)-\operatorname{dist}(i,1)\leq y_j$。

然后对着最短路树想了一万年,感觉我比较智障。这相当于$\operatorname{dist}(i,j)-y_j\leq\operatorname{dist}(i,1)$,于是我们把$j$到自己的距离初始化成$-y_j$,跑多源dij即可。

B. Cowpatibility

bitset。

但是据说可以更快。考虑容斥,枚举一个子集算相等的对数即可,hash table,复杂度$O(2^5n)$。

C. Teamwork

dp,单调栈上二分。对于一段,要查一个区间$\max$,不过容易发现dp值是单增的,所以只需要从最后一个点转移即可。

Pt

A. Balance Beam

怎么感觉跟什么经典凸壳题有点像。

设$dp(i)$表示$i$处的答案,那么$dp(i)=\max(\frac{1}{2}(dp(i-1)+dp(i+1)),f(i))$。

考虑如果确定了哪些位置取$f$,剩下的位置需要满足什么,可以发现如果$i$左边第一个取$f$的距离为$d_l$,右边为$d_r$,那么有$\frac{d_l}{d_l+d_r}$的概率到左边去,也就是说$\frac{d_lf(l)+d_rf(r)}{d_l+d_r}\geq f(i)$。我们把每个点看成$(i,f(i))$,这也就是说选的是上凸壳了。复杂度$O(n)$。那看来就是经典凸壳题,通过搜索可以知道我听过agc044 E. 。

B. Sort it Out

看起来很困难!

考虑一个子集啥时候是合法的,首先子集外必须是有序的,那么既然子集外有序了,我们要么会撞上一个子集内的,要么就到正确位置了。所以也当且仅当子集外有序。于是就是求字典序$k$大的lis,线段树做dag最长路计数,按以$i$为结尾的lis长度塞个vector,一路二分过去即可。

C. The Cow Gathering

也就是说每次只能剥一个叶子呗。

考虑如果一个点要最后走,那就让它当根,树边都指向根。不行当且仅当限制成环,那么考虑环是啥样的,向祖先的边没有用,向后代的边直接成环,或者可以就是走若干横向边,转一圈回来。

感觉上这个其实不太好直接做,因为任意dag都能找个生成树嘛。考虑dfs换根的过程中,每次会有一条边方向改变,这会让有的边变成横向边,有的点对之间的连通性改变这样的,所以考虑怎么做动态图判环啊。考虑类似于xix open cup gp of zhejiang那个题的整体二分,但是这里有删边,所以不太好做啊。

考虑一个环,对于环上每条树上的链,它会ban掉一条链的一侧,也就是保留一条链的另一侧,也就是说我们最后得到的是若干个一条边的一侧这样的东西的交。那么它显然是一个连通块。

感觉比较厉害。考虑如果我们找到了一个答案,以它为根,那么如果$u$在$v$之前走,$u$为根的子树都不能成为答案,而想象一下可以发现,如果一个点没有被这样的限制覆盖,从根出发走到它的路径上只会经过若干入边,不可能生成新的环。所以toposort随便找一个答案,然后前缀和即可。

或者也可以解释为,考虑凑一个充要,如果有$u$在$v$之前,我们以$v$为根,把$u$子树每个点连向父亲,$u$连向$v$。显然这是必要的,所以如果这样就成环了那肯定没救,否则,有出度的点不可能成为答案,没有出度的点是一个连通块,以这个连通块为根如果有环,那么一开始也有这个环,所以只需要随便找一个解,如果能找到的话这个连通块就是答案,否则没救。

为了找到一个解,能删就删即可,也就是一个点只邻接一条树边,并且没有出边就可以删。

Jan.

Au

这么菜?

Cow Poetry

每次确定一个韵部,对每个韵部,枚举一个单词,背包算出以它结尾的方案数即可。

Sleepy Cow Sorting

在最后维护一个有序段。

Shortcut

跑个最短路树。

Pt

Redistricting

dp,那么问题是全局加,加一个数,删一个数,$\geq 0$,$\leq 0$的分别求个$\max$,桶,两个堆即可。

可以线性。类似于xxi poi stage 2 Little Bird,这里转移的代价只有$0,1$,如果插入的比队首小那么直接弹队首,否则比一比前缀和即可。

Exercise Route

也就是求有多少对非树边满足覆盖的链有边的交。链交还是链,类似于 22集训队胡策 R4 B. 【模板】树链剖分,对链交点分治,复杂度$O(n\log n)$。但是这个巨麻烦。

考虑减去不交的,那么直接线段树合并搞搞好像就赢了。

考虑有没有什么简单做法啊!两条路径不交,那么考虑它们的x-center,这是一条链,在链上最高的点处统计,那么四个端点都在这个点子树中,两条链不交当且仅当经过的子树不交,大力统计即可。

Train Tracking 2

让我们想起 abc262 Ex. Max Limited Sequence。看起来那个题确实比这个题强/cf

那么我们就阅读一下题解吧。求出每个位置的上界,那么每个给定区间,所有数都不超过上界,且需要一个数顶上界。从小到大扫值域,发现每个数只有顶不顶上界有关系,每个区间只有有没有上界为它的$x$的数顶到上界有关系,所以上界不同的数是独立的。对于一个上界,把区间离散化,设$dp(i)$表示上次选了$i$的答案,转移要求不能跨过一个区间,所以能转移到的是一个后缀,前缀和优化即可。复杂度$O(n\log n)$,瓶颈在区间对一个数取$\max$。

对于这个题,发现上界相同但是不在同一个$x$的连续段的数也是独立的,所以更简单了一点。

Feb.

Au

Cow Land

lca,dfs序,差分,BiT。

Dishwashing

考虑直接模拟过去,前面的栈中任何一个数必须比后面的栈中任何一个数小,每个栈必须是从上到下递增的。能拿走就拿走是不劣的,插入的时候只有一个可能合法的插入位置,二分出来即可。

Painting the Barn

枚举一条分界线,两侧各跑一个最大和子矩形,复杂度$O(n^3)$。

Pt

Cow Dating

恰好一个奶牛接受邀请的概率,设$s=\prod\limits_i(1-p_i)$,那么也就是$s\sum_i\frac{p_i}{1-p_i}$。那么考虑前缀的$s$和前缀的$\sum\frac{p_i}{1-p_i}$,设它们是$a$和$b$,那么我们就是要最大化$\frac{a_r(b_r-b_l)}{a_l}$,这是$a_rb_r,a_r$和$\frac{1}{a_l},-\frac{b_l}{a_l}$的点积,可以用李超树维护。

但是这里前缀积精度很爆炸,看起来比较有多$\log$做法,但是不是很清真。还是考虑凸壳,这里斜率$\frac{a_r}{a_rb_r}$是递减的,也就是说我们是顺时针扫凸壳,而$\frac{1}{a_l}$是递增的,也就是说我们是从左往右加点。那么这是决策单调的,可以决策单调性分治。

更劲爆的事情是,每个点都在凸壳上,证明考虑改为枚举左端点,因为右端点形式好一点,其实两边是对称的,相邻三个点$i,i+1,i+2$的叉积是$(a_{r+1}b_{r+1}-a_rb_r)(a_{r+2}-a_r)-(a_{r+2}b_{r+2}-a_rb_r)(a_{r+1}-a_r)=a_{r+1}a_{r+2}(b_{r+1}-b{r+2})+a_rb_r(a_{r+2}-a_{r+1})-a_r(a_{r+1}b_{r+1}-a_{r+2}b_{r+2})=-a_{r+1}a_{r+2}\frac{p_{r+2}}{1-p_{r+2}}-a_ra_{r+1}b_rp_{r+2}-a_ra_{r+1}p_{r+2}(b_{r+1}+1)<0$,所以相邻三个点总是顺时针转的,所以每个点都在凸壳上。那么我们直接双指针即可。这里每个点的答案至少是1e-6级别,所以精度就好很多啦。

Moorio Kart

洛谷什么shaber题意。$y$很小,当然转化成求$<y$的方案数,对于每组每棵树上选择的方案有$(k-1)!$种方案连起来,每种都会给长度增加$kx$,所以也就是每棵树上选择的长度和$<y-kx$的方案数,直接把每棵树卷起来即可,但是直接卷是$O(n^3)$,注意到一棵大小为$c$的树只有$\binom{c}{2}$条链,所以其实是$O(n^{2.5})$的。

求长度和只需要加一个元。

好像有人会$O(n^2)$啊,但是我不太懂。

Mowing Mischief

容易发现固定一个方案,答案也就是相邻两个点分别为左下角和右上角的正方形面积之和,那么也就是我们要选一个lis让这玩意最小。设$dp(i)$表示选的点集最后一个点是$i$的答案,那么从$j$转移的贡献就是$(x_i-x_j)(y_i-y_j)$,但是看起来是个三维凸包,有点太极端了。

仔细写写它是$dp(i)=x_iy_i+\max\limits_j (dp(j)+x_jy_j)-(x_iy_j+y_ix_j)$,看起来我们需要找点性质,首先如果两个点之间有一个点,那么肯定不会跨过这个点转移,所以我们只会转移到单调栈上,但是这个好像没啥用。

猜测我们必然选择一个最极端的lis,也就是最上的或最下的,容易知道最上的lis是唯一的,因为如果不唯一则必然有交叉,交叉的话就可以选出一个比它俩都上的。但是好像不是这样。

考虑求出每个点结尾的lis长度,那么我们按这个给点分层,每一层都是单调的,并且只能在相邻层之间转移,并且每个点只能从一个区间转移来。

然后可以猜这玩意是决策单调的,确实是这样,画一画很容易得到一个四边形不等式,但是这里是更倾向于交叉,而还有一个只能从某个区间转移的限制,这导致不交叉的时候我们不总能把它换成交叉的。不过当然注意到这些区间是单调的,看看我们能不能用已有的信息得到一个复杂度正确的做法。

强行分治,设中点$p$可以转移到$[l_p,r_p]$,在其中爆力求出最优决策点$q$,那么能转移到$q$的是一个区间$[l_q,r_q]$,考虑每个点能转移到哪 :

  • $<l_q$ : $<l_p\cup[l_p,q]$

  • $[l_q,p)$ : $<l_p\cup [q,r_p)$

  • $(p,r_q]$ : $(l_p,q]\cup >r_p$

  • $>r_q$ : $[q,r_p]\cup >q$

那么可以注意到寄了对吧。不过画一画这四个区间之间的关系可以注意到,$<l_p$和$[l_p,q]$是对称的,另一侧类似。所以考虑一些根号做法,如果$[l_p,r_p]$很短,我们把前两个case一起递归,后两个case一起递归;如果$[l_p,r_p]$很长,那么$<l_p\cup >r_p$就很短,我们把case 1,3一起递归,2,4一起递归,这样每层决策点长度最多会乘$1.5$,所以复杂度是$O(n^{\log_2 3})$。

但是不是这样,考虑我们直接把这个区间的限制去掉,把区间挂到线段树上,那么每个点都决策单调了,所以直接死妈文科就得到$O(n\log n)$。感觉我还是比较shaber。

Open

Au

A. Snakes

也就是划分成$k$段,最小化每段$\max$的和。容易做到$O(nk\log n)$。

注意到这玩意满足包含优于交叉,所以不用线段树了,可以直接分治。

这是cf1175 G. Yet Another Partiton Problem。

B. I Would Walk 500 Miles

二分答案先,那么也就是说我们要至少$k$个连通块。那就先跑个prim mst,然后只需要看这上面的第$k$大边权之类的。复杂度$O(n^2)$。

但是可以$O(1)$啊。

C. Balancing Inversions

折磨牛。考虑我们每次交换必然可以让一侧的逆序对数增加$1$或减少$1$,然后左边的最后和右边的开头是接着的,交换一次可以让逆序对数变很多对吧。那么枚举中间换了多少次,我们直接让最近的一些$0$和$1$过去,维护这个逆序对数即可,剩下的交换次数就是两侧逆序对数的差,复杂度$O(n)$。

Pt

A. Tree Boxes

这么难?

考虑菊花怎么做,发现斜着排一排就好了。

然后我们就会了,随便选一个根,递归子树,然后把子树们斜着排一排。

B. Compound Escape

这不是我们mst计数的题目吗。大家都知道mst计数就是kru扫过去,每个权值会合并若干连通块,在每组合并中做一个生成树计数然后乘起来对吧。那么每组合并是他妈啥呢,看起来这是个平面图,平面图上的一些连通块之间有一些边,我们要求生成树个数。但是其实我是不会优化的,那不如直接状压轮廓线连通性来dp,记最小值和最小值个数即可。复杂度$O(nB_kk)$,$B$是贝尔数。

评价为rubbish problem。

C. Valleys

那我们扫值域对吧,$<$的是$0$,$>$的是$1$,山谷就是$0$的极大四连通块,满足其中没有洞,这里只有一个连通块被更新的时候我们才考虑它是不是。

问题是怎么判断有没有洞,有洞当且仅当有一个四连通的环,其中有$1$对吧。我们维护连通块右手扶墙的轮廓和其中$1$的个数,合并连通块的时候,找到合并的格子在轮廓上的位置,如果两个格子本来就连通那就产生了一个洞,从轮廓上把它split出来即可。也可能有一个洞变成两个洞之类的,反正这种东西总是能维护的。复杂度$O(n^2\alpha(n))$。

但是这个太shaber了,考虑$v-e+f=2$,这里只需要算出$f$,直接结束战斗。

19~20

只做Pt吧。

Dec.

Pt

A. Greedy Pie Eaters

考虑找到最后选的那个区间,枚举它匹配了哪个位置,然后递归两边。区间dp即可。发现只需要枚举匹配了哪个位置,然后取上面权值最大的区间,复杂度$O(n^3)$。

B. Bessie’s Snow Cow

这不是我们胡策题吗。这是22集训队胡策 R12 C. 树与染色! 。

C. Tree Depth

这不是我们卡笛尔树吗。也就是说求所有恰好$k$个逆序对的排列的卡笛尔树所有点深度和的和。

那么直接对卡笛尔树dp,但是归并的时候很要命。不过可以发现归并的时候跟内部是啥样是没有关系的,所以也就是,设$dp(i,j)$表示$i$个点,逆序对数为$j$的方案数和深度和,转移枚举左子树大小$k$,那么右子树有$i-k-1$个点,设$f(i,j,k)$表示两个分别长$i,j$的序列归并,产生$k$个逆序对的方案数,转移考虑最后一个数来自哪一侧,如果是右侧那就没有贡献,如果是左侧那就贡献$j$个逆序对。复杂度$O(n^8)$。

那么我们知道其实$f(i,j,k)$就是在$0,…,j$中无序地选$i$个数和为$k$的方案数,这是一个两侧都有限制的分拆,看起来其实不好算。那感觉就比较没救了。

别卡笛尔树了。这里是求和,我们直接枚举一个点算它的深度和,那么深度就是两侧的单调栈长度之和$-1$,继续拆成每个位置的单调栈长度之和减去逆序对数为$k$的排列个数即可。dp,设$dp(i,j,k)$表示长$i$,单调栈长度为$j$,逆序对数为$k$的排列个数,那么枚举最后一个数,如果它是$i$那么它在单调栈上,否则$i$在前面出现过了,所以它不可能在单调栈上。同时也可以计算出逆序对数的变化量。统计答案的时候还要和剩下的插起来,不过它们的效果就是不改变$j$这一维了,用另一个dp批量处理即可。然后我们其实没有必要记$j$,因为是求和嘛,这就$O(n^3)$了。

看起来题解做法是枚举$i,j$计算$i$是$j$的祖先的方案数。

Jan.

Pt

A. Cave Paintings

这么难???

考虑设$S(a)$表示$a$填了之后哪些格子要填(包括$a$自己),那么各$S$要么不交要么包含,也就是说缩起相等之后形成了一棵树,我们相当于选择若干子树去填,如果求出这棵树,只需要树dp即可。

那么问题是怎么求出这棵树,显然相等的在同一行中,并且自底向上一层一层加边,那么扫到一行时每个连通块都是相等的,然后为了找到儿子,只需要往下连边即可。复杂度$O(n^2\alpha(n))$。

然后也不需要显式建出树来,扫的过程中每个连通块都是一棵子树,直接每个连通块维护一个答案即可。

B. Non-Decreasing Subsequences

直接线段树呗。复杂度$O(nk^2\log n)$。

考虑把转移写成矩阵乘法,那么可以发现它是有逆的,复杂度$O(nk^3)$。但是其实可以$O(nk^2)$,考虑如何才能把所有东西变成矩阵乘向量,设$dp(i)$表示结尾为$i$的方案数,那么我们要算一个前缀的矩阵倒着乘起来,乘上另一个前缀的逆正着乘起来,然后乘上初始只有$dp(1)=1$的向量。这看起来是没法做的。但是注意到我们只需要求$dp$的和,也就是说相当于左边有一个全$1$的行向量,那么把前一半和这个行向量乘起来,后一半和列向量乘起来即可。

C. Falling Portals

如果要往上走,我们会希望走到尽可能慢的位置。如果要往下走,我们会希望走到尽可能快的位置。能走就走必然是不劣的,所以我们已经会单次$O(n^2)$啦。

看起来需要一些性质了。把每个点看成一条直线,那么相当于我们从某个时刻出发,遇到斜率更小的就走过去这样的,那么走出来就是一个凸的形状。考虑从小到大扫$a_i$,维护上包络线,这部分是$O(n)$的,然后查询只需二分一次。复杂度$O(n\log n)$。

Feb.

Pt

A. Delegation

先看看Au的A,那么直接自底向上做,记录长度即可。

现在我们要最大化最小值,那么当然二分,还是直接自底向上做,如果有多条链则留尽可能长的,那么怎么留尽可能长的呢,如果确定了留哪个,为了满足限制我们肯定让最长的拼最短的,次长的拼次短的,这样的,因为如果不是这样,向这样交换必然可以让换的部分的$\min$变大。直接枚举留了哪个,每次移动的时候配对变化量$O(1)$,长剖计排即可做到总共$O(n\log n)$。我怎么记得这是个arc题。

B. Equilateral Triangles

考虑等边三角形有啥性质。曼哈顿距离下的圆是斜的正方形,先画一个斜的正方形,在上面标一个中心再画一个,然后看它俩的交对吧。交可能有很多,但是这种事情只会发生$O(1)$次,所以总长还是$O(n)$的。可以通过拆开绝对值嗯解方程得到所有的解。总复杂度$O(n^4)$。

但是这个还是太菜了!ix35说的好,我们可以找到一个点最小化到这三个点的距离和,如果这是等边三角形,那么这个点必然是它的外心。那么枚举这个外心,枚举外接圆半径$r$,此时由于它到三个点的距离和最小,必然有一个点在上/下$r$的距离,另一个点在左/右$r$的距离,第三个点在那个不包含这两个点的象限里。所以第三个点是一条斜线,斜着做前缀和即可,复杂度$O(n^3)$。

C. Help Yourself

那么我们当然每次钦点一个连通块对吧。这不是sdcpc23 F吗?

具体地,设$dp(i)$表示最后一段右端点在$i$的方案数,那么从$i$转移到$j$的话,所有包含在$(i,j]$的区间都可以选,且右端点在$j$的那个区间必须选。考虑$i$对$j$的贡献,从右往左扫,每次碰到一个右端点就是后缀$\times 2$,线段树优化即可,复杂度$O(n\log n)$。

Open

Pt

A. Sprinklers 2: Return of the Alfalfa

这么难???

考虑我们是画了一条分界线,两侧可以随便放,但拐角处必须放。直接对分界线进行dp即可。

B. Exercise

那么也就是说对所有排列算环长lcm的乘积对吧。那么我们枚举一个素数$p$,计算多少个排列的环长lcm包含$p^k$,也就是说至少一个环包含$p^k$,那么转而计算没有环包含$p^k$的方案数,也就是说一些环长被ban掉了,任意环exp的egf是$\frac{1}{1-z}=\prod_i e^{\frac{1}{i}z^i}$

C. Circus