CF1912J Joy of Pokémon Observation 记录

题目链接:https://codeforces.com/contest/1912/attachments/download/23419/icpc-nerc-2023-statements.pdf

题意简述

求方程 i=1slixi=t 的非负整数解的个数。

不多于 1024 组用例,t109,s3,li16

题解(官解)

赛时我光想着怎么求一般方程的解的个数了,没找到什么有用的结果,结果 li16 的条件很重要。

s=1 时很显然,若 t0modl1,答案为 1,否则为 0

s=2 时,即求 aia+bib=l 解的个数。令 ia=kab+ja,枚举 ja,方程变形为 kaa+ib=tajab:=r。则在右侧为整数时,需要向答案添加 ra+1,因为对每个 kaar,都恰存在一个 ib

同理,s=3 时,即求 aia+bib+cic=l 解的个数。令 ia=kac+jaib=kbc+jb,枚举 jajb,则方程转化为 kaa+kbb+ic=tajabjbb:=r。若右侧为整数,即等于找到 kaa+kbbr 的解的个数。

再令 ka=rab+ea,枚举 ea,变形为 ara+kbraeab:=g。枚举 ra,向答案中加入 1+gara。枚举 ra 的复杂度并不过关,但注意到这部分是一个等差数列,故可以 O(1) 求解。

单组测试时间复杂度 O(l3)

代码实现(C++)

void solve() {
int n, t;
cin >> t >> n;
if (n == 1) {
int a;
cin >> a;
cout << (t % a == 0) << "\n";
} else if (n == 2) {
int a, b;
cin >> a >> b;
i64 ans = 0;
for (int ja = 0; ja < b && a * ja <= t; ja++) {
if ((t - a * ja) % b == 0) {
int r = (t - a * ja) / b;
ans += (r / a) + 1;
}
}
cout << ans << "\n";
} else {
int a, b, c;
cin >> a >> b >> c;
i64 ans = 0;
for (int ja = 0; ja < c && a * ja <= t; ja++) {
for (int jb = 0; jb < c && a * ja + b * jb <= t; jb++) {
if ((t - a * ja - b * jb) % c == 0) {
int r = (t - a * ja - b * jb) / c;
for (int ea = 0; ea < b && a * ea <= r; ea++) {
int g = (r - a * ea) / b;
int n = g / a + 1;
ans += (i64)(g + g - g / a * a) * n / 2 + n;
}
}
}
}
cout << ans << "\n";
}
}
posted @   cccpchenpi  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示