/ Record 10

Created Thu, 01 Oct 2026 00:00:00 +0000 Modified Tue, 13 Oct 2026 12:47:45 +0800
1573 Words

重新训一点 oi,不是很明确方向。犹豫了好几天,最后觉得「开始做」比「思考做什么」更重要,所以直接耍起。

THUPC

P14840 \[THUPC 2026 初赛\] 宝石分组

10/1。

首先,多次查询最优化答案,答案还取模,肯定是事先确定好策略然后计算。显然首先可以排序。先考虑最简单的情况,假设没有组大小限制,怎么分。发现对于两个和分别为 $a,b$ 的段,合并总劣于分裂

$$ 2\left(\frac{a+b}{2}\right)^2\le a^2+b^2 $$

当然这里都非负,同时扩展到更高维同样成立,即应该尽量拉开差距,可用向量证。

思考了一段时间,这样好像对分组没有很直观的指导意义:对于相邻的两个段也要拉开吗?怎么拉?于是换了一个角度。我们猜每段肯定是尽量远离平均数,即

$$ \begin{aligned} &\sum\left(a_i-\overline{a}\right)^2\\ =&\sum a_i^2-2\overline{a}\sum a_i+n\overline{a}^2\\ =&s_2-\frac{s_1^2}{s_0} \end{aligned} $$

即让每个段和尽可能极端。但这里写的时候才发现不太对,把平均数和总和混淆了。后面推导出段应该尽量长,全倒了。做成了权值为和的平方 /xk。应该是让每一段尽可能短。

最后得到结论,从大到小排序后取 $\lfloor n/l\rfloor$ 段 $l$,一段 $(n\bmod l)\bmod (r-l)$(为 $0$ 则没有),最后 $\lfloor(n\bmod l)/(r-l)\rfloor$ 段 $r$。其实这个也不够严谨。最后具体实现、判无解又出了一车问题,翻来复去地调。


快做吐了,过的时候只有苦笑,这种还享受乐趣个蛋。但还是要练。

这一道题做了大半天,想了 3h 写了 2h。以后可以考虑做题计时,首先限制思考时间,磨磨蹭蹭地想必须改掉。

其次写尽量精准,不要怕想细节,不要自以为是。

for(int l,r;q--;)
{
	cin>>l>>r;
	if(n%l&&l==r){puts("-1");continue;} // cannot adjust
	int R,x,L;
	if(l==r)L=n/l-1,x=0,R=0;
	else R=(n%l)/(r-l),x=(n%l)%(r-l),L=n/l-R-bool(x);
	if(L<0){puts("-1");continue;}
	ll ans=(pre[l][L]+suf[r][R])%mod;
	ans=(ans+sq(s[n-R*r]-s[L*l])*inv[n-R*r-L*l])%mod;
	printf("%lld\n",ans);
}

就这样一段写不清楚,我的细节思考能力确有问题!可以把情况讨论清楚,让逻辑清晰。复杂逻辑就不要合并或者走小道了。比如这里分母为 $0$ 干脆判掉。而且无解情况处理也不够好,这种分开来又增加了逻辑复杂度,难想难调。

类似寄法:CSP-J 2023 T3 一元二次方程(uqe);CSP-S 2024 T2 超速检测(detect);

P14839 \[THUPC 2026 初赛\] 集合

10/2。已思考 43min 04s,失败。

首先考虑只有 $A\cup B$ 中的元素有用。双序列的结构,马上可以想到一个 $f_{i,j}$ 表示选到 $A_i,B_j$ 时最小 $|C|$。但这个东西非常奇怪,转移自由得有点诡异。具体而言,可以一直转移其中一维,然后另一边不管。一开始猜是用 ds 优化 dp,但是这个形态无法优化。

试图分三种情况:转移 $A$、转移 $B$、转移 $A,B$ 中均有的元素,但也没什么用。

换了一种设计,直接按 $A\cup B$ 中从小到大 dp。但是这样会丢失信息,不知道另一个上一个是哪个。

最后又回到 2D,限制 $B_j\le A_i$(或 $A,B$ 交换),这样就类似交替决策。共用点可能要特殊处理。最后还是一头雾水,就放弃了。


看题解这题有官解(1D/1D)和爆标(2D/0D)两种做法,分别对应我想的两个方向(实则不然,有点差距)。由于官解太复杂我看不懂,先学爆标。

对于转移太怪异的情况,由于 $f$ 有单调性,只需要尽可能远地转移,同时可以钦定转移顺序从小到大,这样就规整多了。

然后由于不能回头加数,所以 $i,j$ 直接就有了羁绊。$A_i+a\ge B_j\land B_j+b\ge A_i$ 即 $A_i-b\le B_j\le A_i+a$。设 $a\le b$,那么让 $j$ 超过 $i$ 就只需要跳 $O(1)$ 次。也就是说对于一个 $i$,有意义的 $j$ 个数是 $O(1)$ 的。

于是设 $f_i$ 表示前缀最小值,$g_{i,f(i)+j}$ 表示选到 $i$,集合大小为 $f_i+j$ 时 $B$ 上最大能取到多少。

【尚未完全理解】

【卡在哪了】

以后看题解也得计个时。发现以前经常不好好补题,没有理解清楚就糊过去。无论如何理解做法总结卡点都是重要的,不然不如不做。

P14837 \[THUPC 2026 初赛\] My Mayday

10/9 思考未计时。

第一问求最小时间应该是比较简单的,直接从上往下贪心即可,具体怎么做没有细想。

要计数合法的方案,只能设计 dp。考虑从左往右,从上往下,划分 01 交界。但是这样好像不太行。

看了一下标签是区间 dp。考虑从右往左,即从低位到高位,发现就是一个把区间划分为 01 两连续段,然后分别让子状态保证合法性。设 $f(i,l,r)$ 表示考虑到第 $i$ 位,区间 $[l,r]$ 内的数的方案数。转移时枚举分界点 $j$ 合并即可

$$ f(i,l,r)\xleftarrow{+}f(i-1,l,j)\times f(i-1,j+1,r)\qquad a[l,j]\subseteq\{\texttt{0.}\}\land a[j+1,r]\subseteq\{\texttt{1.}\} $$

最大值 $a_n$ 是要特殊处理的,求出最小上界之后要限制 $[x,n]$ 的转移。通过在转移中控制的方式保证 $a_n$ 合法。


还是没有掌握 dp 的一般考虑方法。