897 字
2 分钟
Atcoder_Beginner_Contest_473(A~E题)
2026-09-01
浏览量 14 · 访客 3

壁纸链接
题目链接:https://atcoder.jp/contests/abc473/tasks

A - Second Half Sum#

因为NN为偶数,序列后半部分的下标范围为N2+1\frac{N}{2}+1NN。读入序列时只累加满足iN2+1i\geq \frac{N}{2}+1的元素即可。时间复杂度为O(N)O(N),额外空间复杂度为O(1)O(1)

void solve(){
int n; cin >> n;
int sum = 0;
for(int i = 1; i <= n;i++){
int x; cin >> x;
if(i >= n / 2 + 1) sum += x;
}
cout << sum << endl;
}

B - Old Maid#

对于值为xx的卡片,设其出现次数为cntxcnt_x。每次操作会删除两张相同的卡片,所以最终剩余数量只由cntxcnt_x的奇偶性决定:偶数张可以全部配对删除,奇数张会剩下一张。
因此先统计每个整数的出现次数,再将所有出现次数为奇数的整数值累加到答案中。使用mapmap统计时,时间复杂度为O(NlogN)O(NlogN),空间复杂度为O(N)O(N)

void solve(){
int n; cin >> n;
map<int, int> mp;
for(int i = 1; i <= n;i++){
int x; cin >> x;
mp[x]++;
}
int ans = 0;
for(auto it : mp){
if(it.second & 1) ans += it.first;
}
cout << ans << endl;
}

C - Change Schools#

先统计每个班级当前的人数cnticnt_i,并求出全局最大人数ma=maxcntima=\max cnt_i。如果选择第ii个班级,加入后该班人数会从cnticnt_i变为cnti+1cnt_i+1,要使其不小于其他所有班级的人数,必须满足cnti+1macnt_i+1\geq ma
因此合法班级恰好是当前人数等于mamama1ma-1的班级。人数为mama时加入后会成为新的最大值,人数为ma1ma-1时加入后会追平当前最大值;更少的班级加入一人后仍小于mama。遍历所有班级统计这两类即可。时间复杂度为O(N+K)O(N+K),空间复杂度为O(N+K)O(N+K)

void solve(){
int n, k;
cin >> n >> k;
vector<int> a(n + 1, 0);
vector<vector<int>> b(k + 1);
for(int i = 1; i <= n;i++){
cin >> a[i];
b[a[i]].push_back(i);
}
int ma = 0; ll cnt = 0;
for(int i = 1; i <= k;i++)
ma = max(ma, (int)b[i].size());
for(int i = 1; i <= k;i++){
if((int)b[i].size() == ma || (int)b[i].size() == ma - 1)
cnt++;
}
cout << cnt << endl;
}

D - Coefficient Stair#

需要枚举所有满足 i=1NiAi=K\sum_{i=1}^{N}iA_i=K 的非负整数序列。使用深度优先搜索依次确定A1,A2,,ANA_1,A_2,\ldots,A_N。当正在确定AxA_x且剩余权值为restrest时,AxA_x的取值范围为00restx\lfloor\frac{rest}{x}\rfloor;选择ii后递归处理下一维,并将剩余权值更新为restx×irest-x\times i
到达最后一维时,ANA_N已被剩余权值唯一确定。只有restrest能被NN整除时才存在合法取值AN=restNA_N=\frac{rest}{N},此时输出整个序列。这样不会遗漏方案,也不会重复输出。
为了保证字典序,DFS在每一维都按从小到大的顺序枚举当前值。较前位置的值更小的序列会先完成整棵子树,因此最终输出顺序自然为字典序。N=1N=1时唯一答案为(K)(K),可以直接输出。空间复杂度为递归深度O(N)O(N);时间复杂度与DFS访问的状态数以及输出量成正比,而输出qq个序列本身至少需要O(qN)O(qN)的时间。

int n, k;
vector<int> a;
void dfs(int x, int rest){
if(x == n){
if(rest % n == 0){
a[n] = rest / n;
for(int i = 1; i <= n;i++){
cout << a[i] << ' ';
}
cout << '\n';
}
return;
}
for(int i = 0; i <= rest / x;i++){
a[x] = i;
dfs(x + 1, rest - x * i);
}
}
void solve(){
cin >> n >> k;
a.resize(n + 1);
if(n == 1) {cout << k << '\n'; return;}
dfs(1, k);
}

E - K-Divisible Subarrays#

将原序列任意分段后,得分只来自区间和能被KK整除的段。所有未被选入这些得分段的位置都可以单独分段或并入相邻的无贡献段,不会降低已有得分。因此问题等价于选择尽可能多的、两两不相交且区间和能被KK整除的非空子数组。
定义前缀和模KK的余数为Pi=(A1++Ai)modKP_i=(A_1+\cdots+A_i)\bmod K,并令P0=0P_0=0。区间(j,i](j,i]的元素和能被KK整除,当且仅当Pj=PiP_j=P_i。再定义dpidp_i表示前ii个元素中最多能选择多少个合法且互不相交的子数组,则有两种转移:不以ii结尾时继承dpi1dp_{i-1};选择某个以ii结尾的合法区间(j,i](j,i]时,贡献为dpj+1dp_j+1
直接枚举所有jj会达到O(N2)O(N^2)。代码用best[r]best[r]维护所有已经处理过且Pj=rP_j=r的位置中最大的dpjdp_j,于是 dpi=max(dpi1,best[Pi]+1)dp_i=\max(dp_{i-1},best[P_i]+1)。 计算完dpidp_i后,再用它更新best[Pi]best[P_i]。初始状态best[0]=0best[0]=0对应空前缀。使用unordered_mapunordered\_map时,期望时间复杂度为O(N)O(N),空间复杂度为O(N)O(N)

void solve(){
int n, k; cin >> n >> k;
vector<int> a(n + 1, 0);
for(int i = 1; i <= n;i++) cin >> a[i];
unordered_map<ll, int> best;
best[0] = 0;
ll pre = 0;
int dp = 0;
for(int i = 1; i <= n;i++){
pre = (pre + a[i]) % k;
int ndp = dp;
if(best.count(pre))
ndp = max(ndp, best[pre] + 1);
dp = ndp;
if(best.count(pre))
best[pre] = max(best[pre], dp);
else best[pre] = dp;
}
cout << dp << '\n';
}

模板:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define mod 998244353
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
ll fast_pow(ll a, ll b, ll MOD){
ll ans = 1;
while(b){
if(b & 1) ans = (ans * a) % MOD;
b >>= 1;
a = (a * a) % MOD;
}
return ans;
}
vector<ll> get_inverse(ll n, ll MOD){
vector<ll> inverse(n + 1, 0);
inverse[1] = 1;
for(int i = 2; i <= n;i++){
inverse[i] = MOD - (MOD / i) * inverse[MOD % i] % MOD;
}
return inverse;
}
void solve(){
}
int main(){
ios::sync_with_stdio(false),
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
//cin >> _;
while(_--){
solve();
}
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Atcoder_Beginner_Contest_473(A~E题)
https://mkrari.cn/posts/abc_473/
作者
Mkrari
发布于
2026-09-01
许可协议
CC BY-NC-SA 4.0