部分思维题

一些题单(非本人创建):

思维题题单(普及~提高难度)

思维题

眼前一亮思维题

直接看可能直接知道结论就没意思了,可以先去题单看题。

Part 1.easy problem

有些神秘题,有些一眼题。

P12028 [USACO25OPEN] Moo Decomposition G

注意到答案肯定是 \(ans^l\)\(ans\)\(S\) 的方案数,原因显然,因为每一段都是完美匹配。

或者说这么想,你从后往前,如果是 M\(ans \times C_{len,k},len-k\),否则 \(len+1\)

然后如果最后一段处理完有剩余,那么下一段也会剩这么多,然后就一定不会为空显然不可能,所以每一段独立。

code

P13098 [FJCPC 2025] 构造大师贝贝

题如其名。

不重复,完全平方数,\(100\) 次。

问题在于,每次加 \(x\) 的话会搞得很混乱,而且根据此题数据范围求因数根本是不现实的。

我们考虑二进制,因为二进制下有个很好的性质,我们从小往大加,是无后效性的(即低位不会突然又多出来几个位置变成 \(1\))。所以我们直接每次加 lowbit,知道 \(n\) 为平方数结束,注意到 \(2^i,2^{i+1}\) 两个至少有一个是平方数,这个显然,然后次数可以保证。

code

P5502 [JSOI2015] 最大公约数

带点思维也是思维题

gcd,暴力数据结构,分治。

UVA1642 魔法GCD Magical GCD P7009 [CERC2013] Magical GCD

重题。

考虑一个很经典的东西,\(\gcd\) 的变化量级应当是 \(\log\) 的,你固定左端点,然后 \(\gcd\) 最多变 \(\log\) 次,这个很显然,你变一次至少少一个 \(2\),那不就 \(\log\) 次了。

然后你可以枚举左端点,暴力看 \(\log\) 个变化点,复杂度 \(log^3\),不太好过(其实常数很小)。

考虑枚举右端点,为啥捏,因为一个好的性质我们可以利用,就是注意到 \(\left(l,r\right)\)\(\gcd\) 一定 \(\ge \left(l,r+1\right)\)\(\gcd\),所以 \(r\) 增加,原来的那些区间最多合并,不会分裂,就比如你知道 \(x\) 与这段区间的 \(\gcd\)\(y\),那么 \(\frac{x}{z}\) 与这个区间的 \(\gcd\) 肯定不会大于 \(y\)

code

P9900 『PG2』消除萝卜 B

诈骗完了。

注意到 \(a_{i,1} \ne a_{i,2}\),考虑你在 \(a_{1,j} = 1\) 的下面加一个 \(1\),此时许多 \(1\) 的段都和一起了。

最后来一次给白色全删完即可,答案就是两个纵列 \(1\) 的颜色段去最大值加一。

code

P11919 [PA 2025] 水族馆 / Akwarium

考虑枚举 \(i\),然后 \(a^2+b^2+h^2 = i^2\)

为了避免算重我们在枚举一个 \(b\),求 \(a^2+h^2 = i^2-b^2\)

考虑交换枚举顺序,先枚举 \(b\),每次左边都会多 \(n\) 种可能,拿桶记一下即可,复杂度和空间皆为 \(n^2\),不知道有没有更优的。

code

P13096 [FJCPC 2025] 难以控制的滑板火箭

容易发现,你走肯定是直接走过去,然后走多了就一直来回跳就好了,因为你每远离一次,接下来就多需要一次回来,所以从最后点开始必须要相差偶数步才行。

一个显然的结论,对于区间 \(l,r\),你走 \(x\) 次,那么你就可以走 \(l\times x\)\(r \times x\) 中的任意一个,考虑求出步数为奇数和偶数的两个最短路,如果存在 \(x\) 使得包含,那么取最小的 \(x\) 即可。

否则直接分讨,只跟奇偶性有关分别求出到这的最小奇数步和偶数步,然后如果 \(l=r\),选择就固定了,否则我们可以通过调整法使得强行改变奇偶(即有一步不走 \(r\),走 \(r-1\)),具体分讨过程可见代码。

code

Part 3.hard+ problem(含 Ad-hoc)

P12264 『STA - R9』咏叹调调律

老师:这题就是纯 Ad-hoc 题,想到了你就会了。

可以先考虑弱化版:包含 AACB 这种形式,可以做 \(n = 5000\)

像这种能不能表示成若干子序列的组合的类型我们见的比较少,而且本题的数据规模也相当大。思考有没有什么简化问题是我们做过的?——括号匹配。

考虑给 \(A,B,C\) 都转化一下,注意到 \(C\) 始终在左边,\(B\) 始终在右边,考虑分配给 \(C\) 一个左括号,\(B\) 两个右括号,此时 \(A\) 可以是两个左括号或一个右括号。

发现对于任意合法序列,一定存在一种映射方式使得得到的括号序列合法。

显然对于每个括号序列只要合法,也一定至少存在一种映射方式可以映射回去,在弱化版只要是合法的括号序列就合法。

由于 \(A\) 有两种选择,很有可能算重,考虑每次删子序列,考虑让前缀的 \(A\) 当左括号,后面的当右括号显然不劣。考虑 \(f_{i,j,0/1}\) 表示前 \(i\) 个有 \(j\) 个左括号,现在 \(A\) 是左括号还是右括号的方案数,为了不算重,只有在进行 A 为右括号的时候额外用一下 \(f_{i,j,0}\) 转移,转移看着转即可。

code

考虑原题没有 \(AACB\),那么 \((()())\) 是不行的,考虑我们不让两个右括号匹配一个 \(A\) 的左括号和 \(C\) 的左括号即可,考虑多设点状态,表示双括号有 \(j\) 对,单括号有 \(z\) 个,是否有一个单独的双括号(也就是匹配了一半),是否可以退回一个(也就是一半)双括号然后拿走一个单括号,\(f_{i,j,z,0/1,0/1,0/1}\)

转移看着转即可,比如你用 \(A\) 时优先看是否有剩下来的双括号,有的话就用掉。否则就优先用双括号的一个。

\(B\) 的话就先看双括号有没有大于 \(0\) 对,有就减一,否则就看能否回退。还不行就看单括号有没有两个。

具体可以见代码。code

posted @ 2025-10-26 12:54  kkxacj  阅读(9)  评论(0)    收藏  举报