NOI Online 题解

[NOI Online #1 提高组]序列

首先对两个序列作差,等价于该序列能否变成一个全为 \(0\) 的序列。

对于操作 \(2\) ,连边后等价于一个连通块内和不变,任意加减,所以可以把这个连通块缩点,把和作为权值。

对于操作 \(1\)

同样先连边。

对于一个连通块内如果不是二分图(有奇环),可以在总和奇偶性不变的情况下任意加减,因为一切不必要的操作可以在奇环中消掉(将奇环理解为自环)。

如果是二分图,每次都是两个不同部分的操作,而操作的差相同,因此可以在两部分差不变的情况下任意加减。

时间复杂度: \(O(N\log N)\)

[NOI Online #1 提高组]冒泡排序

首先观察经过一轮冒泡排序排列的变化:

4 3 5 1 2

3 4 2 1 5

可以发现,前面有更大的数(即有逆序对)就会往前一位(前面的数过来)。

也就是说每次操作每个逆序对减少 \(1\) (除了已经是 \(0\) 的)

考虑不带修改操作的怎么做:先把最初的逆序对处理出来,只有那些初始逆序对数大于 \(k\) 的有贡献。贡献为这些的和减掉个数乘以 \(k\) 。用树状数组维护。

接下来考虑有交换操作的,只需要分类讨论对逆序对的贡献即可。

时间复杂度: \(O(N\log N)\)

[NOI Online #1 提高组]最小环

首先一个结论:大的数和大的乘,小的数和小的乘。证明考虑交换两个数,一个积没变,一个变小。

接下来考虑如何放置能够满足这个结论:

这些乘积会形成 \(\gcd(k,n)\) 个闭环。

证明:设相隔 \(k\) 个,能放 \(x\) 个,走了 \(y\) 次环,使正整数 \(x,y\) 最小。

\[xk=yn \]

\[x=\frac{yn}{k} \]

\[y=\frac{k}{\gcd(n,k)} \]

\[x=\frac{n}{\gcd(n,k)} \]

则有 \(\frac{n}{x}=\gcd(k,n)\) 个闭环

对于每个环,先放最大的,接着;两边交替放剩下的最大的即可。

\(\gcd(x,n)\) 会有 \(\operatorname{d}(N)\) 种取值,因此对 \(N\) 的因数先预处理出来即可

注意特判。

时间复杂度: \(O(N\operatorname{d}(N))\)

[NOI Online 2 提高组]涂色游戏

不妨设 \(p_1\ge p_2\) ,随意染色显然选择红色,这个 \(10^{20}\) 可以看做无穷大。

  • 先看个奇怪的条件:就是随意染色。

显然选择红色(\(p_1\))因为它左右一定都是蓝色(\(p_2\)

最大的一段连续颜色显然是这样的: \(mp_1<np_2<(n+1)p_2<\cdots<(n+k)p_2<(m+1)p_1\)

\(t=np_2-mp_1\ (t>0)\) 最小时, \(k\) 最大。

那么可以得到 \(mp_1+np_2=-t\)

根据裴蜀定理,我们知道 \(mp_1+np_2=-t\) 有解当且仅当 \(\gcd(p_1,p_2)|-t\)

\(m,n\) 是什么不重要,因为只需要 \(t\) 就能求出 \(k\) 是多少。

显然 \(t=\gcd(p_1,p_2)\)

然后就可以求出 \(k=\frac{p_1-t-1}{p_2}\) (下取整)

不过实际的 \(k\) 还要 \(+1\) ,再和题面给出的 \(k\) 比较大小即可。

注意特判。

[NOI Online #2 提高组]子序列问题

注:这个题解的做法比较难看,而且只有一份很丑的代码,之后再修改

考虑维护每次 \(l\) 改变后的答案的变化:

首先看 \(l=1\) 的情况:

如果第 \(i\) 个数前面没有和它相同的,那就对 \(f(l,i)\)\(f(l,N)\) 有贡献。

接下来 \(l=i(i\not=1)\) 时:

考虑 \(l-1\) 没有了贡献,而下一个值和 \(A_{l-1}\) 的就能对后面产生贡献,设此处下标为 \(x\) ,则 \(f(l,l)\)\(f(l,x-1)\) 的贡献都减 \(1\)

如何维护这些函数的平方的和呢?同样考虑维护每行的和,再减去差值。

首先维护出每个数的后继并顺便判断前面是否有相同的值。

第一行的和可以第一次迅速求出来。接着若有 \(x\) 个地方值减了 \(1\) ,原来和为 \(s\) 则平方之和减少了 \(2s-x\)

用线段树维护和,时间复杂度: \(O(N\log N)\)

[NOI Online #2 提高组]游戏

难以求出恰好为 \(K\) 的方案,因为钦定 \(K\) 个后难以保证其它点没有子孙关系。

可以使用二项式反演将至少转化为恰好,只要钦定 \(K\) 个就好了。

接下来考虑如何钦定 \(K\) 个,使用树形 DP :

\(F_{x,y}\) 为在 \(x\) 的子树内,钦定了 \(y\) 对子孙关系,可以用背包转移,并额外加上根节点的贡献。

由于是在树上,所以背包时加上树的大小的限制时间复杂度是 \(O(N^2)\) 的。

[NOI Online #3 提高组]水壶

大水题,没啥好写的。

[NOI Online #3 提高组]魔法值

首先这个是否有贡献是和魔法值无关的,只和图长的样子有关。可以考虑计算城市之间互相的贡献,由于是异或运算,只会是 \(0\)\(1\)

之后可以用普通的矩阵乘法计算。如用 bitset 优化,理论上是可以过掉这个题的,但不能开 O2 就被卡掉了。

这个多组询问比较奇怪,考虑优化单次询问的复杂度。

如果跟图有关复杂度总是太大了,可以将图给预处理出来,即计算第 \(1,2,2^2,2^3,\cdots,2^{30}\) 天点之间的贡献。

接着用初始魔法值矩阵和这个预处理的矩阵相乘,复杂度是 \(O(N^2)\) 的。正确性等于是过了几天又重新计算。

时间复杂度:预处理 \(O(N^3\log A_i)\) ,询问 \(O(QN^2\log A_i)\)

[NOI Online #3 提高组]优秀子序列

看这个欧拉函数加来加去是没有任何性质的,只能先将每种值能凑出来的方案数求出来,再套进欧拉函数求和。

先把 \(0\) 给特判掉, \(0\) 怎么与都是不会有冲突的,最后贡献乘上 \(2^{0\text{的个数}}\) 即可,同样空集也要加上去。

既然是二进制下的运算,先转成二进制考虑,每个数是个至多 \(18\)\(1\) 的集合。

每个数都是由其若干子集组成,可以枚举子集来转移。由于题目中规定是有序的,因此枚举时也要有顺序,考虑从大大小,因为每一位只能由一个数占掉,因此必有一个数大于其它所有数之和,每次用这个数转移。

会有多个一样的数,因此该换成某个值有若干个数,计算方案数时也很方便。时间复杂度: \(N+3^{\log A_i}\)

复杂度证明:\(\sum_{i=1}^{N} C_{N}^{i}\times 2^i=\sum_{i=1}^{N} C_{N}^{i}\times 2^i\times1^{N-i}=(2+1)^N=3^N\)

posted @ 2020-10-28 22:16  shrtcl  阅读(278)  评论(0编辑  收藏  举报