重新训一点 oi,不是很明确方向。犹豫了好几天,最后觉得「开始做」比「思考做什么」更重要,所以直接耍起。
THUPC
P14840 [THUPC 2026 初赛] 宝石分组
首先,多次查询最优化答案,答案还取模,肯定是事先确定好策略然后计算。显然首先可以排序。先考虑最简单的情况,假设没有组大小限制,怎么分。发现对于两个和分别为 $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);