AtCoder Beginner Contest 359 补题记录(A~E,G,G 暂无代码)
A
直接统计 Takahashi
出现次数即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2000100;
int a[N];
signed main() {
int n;
cin >> n;
int cnt = 0;
while (n--) {
string s;
cin >> s;
if (s == "Takahashi") cnt++;
}
cout << cnt << '\n';
return 0;
}
B
直接记录每种衣服的两个人出现的位置即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2000100;
int a[N];
vector<int> scc[N];
signed main() {
int n;
cin >> n;
n <<= 1;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
scc[a[i]].push_back(i);
int cnt = 0;
for (int i = 1; i <= n / 2; i++)
if (abs(scc[i][1] - scc[i][0]) == 2)
cnt++;
cout << cnt << '\n';
return 0;
}
C
从这里开始变的
首先纵向的走是没有办法省事的,距离是多长就需要走多少步才能移动到下一条直线上。
横着走的话,首先在同一个
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2000100;
int a[N];
vector<int> scc[N];
signed main() {
int sx, sy, tx, ty;
cin >> sx >> sy >> tx >> ty;
if (sy == ty && sx / 2 != tx / 2 && abs(sx / 2 - tx / 2) == 1) cout << "0\n";
else {
if (sx == tx || abs(sx - tx) == 1)
cout << abs(sy - ty) << '\n';
else {
int len = abs(sy - ty);
if (sx > tx) {
if ((sx + sy) & 1) sx--;
if (~(tx + ty) & 1) tx++;
} else {
if (~(sx + sy) & 1) sx++;
if ((tx + ty) & 1) tx--;
}
int heng = abs(sx - tx);
int len2 = max(len, heng) - len;
len2 = (len2 + 1) / 2;
// cout << "dbg " << len << ' ' << len2 << '\n';
cout << len + len2 << '\n';
}
}
return 0;
}
D
大 dp。设 ?
的情况就是把 A
和 B
的情况分别跑一遍。A
和 B
情况基本等价,都是暴力枚举上一个状态,然后计算出当前的状态,判断是否当前状态或者上一个状态回文,这个因为长度 5.5K
的代码。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4110, mod = 998244353;
int f[N][N];
bool check(string s) {
string t = s;
reverse(t.begin(), t.end());
return s == t;
// return 0;
}
int n, k;
string s;
string dogs(int x) {
string t;
for (int i = 0; i <= k; i++)
t = t + (char)(x % 2 + '0'), x /= 2;
reverse(t.begin(), t.end());
return t;
}
signed main() {
cin >> n >> k >> s;
s = ' ' + s;
// while (true) {
// int s;
// cin >> s;
// cout << dogs(s) << '\n';
// }
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
if (s[i] == 'A' || s[i] == 'B') {
if (i <= k) {
for (int j = 0; j < (1ll << k); j++)
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
// 从k1转移到k2
string now;
int k22 = k2;
for (int p = 1; p <= i; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (i < k || !check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
}
} else {
for (int j = 0; j < (1ll << k); j++) {
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
// 取出 k2 的最高位
string tok2 = dogs(k2);
k2 = 0;
for (int i = 1; i < tok2.size(); i++)
k2 = k2 * 2 + tok2[i] - '0';
string now;
int k22 = k2;
for (int p = 1; p <= k; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (!check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
}
}
}
} else {
s[i] = 'A';
if (i <= k) {
for (int j = 0; j < (1ll << k); j++)
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
// 从k1转移到k2
string now;
int k22 = k2;
for (int p = 1; p <= i; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (i < k || !check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
}
} else {
for (int j = 0; j < (1ll << k); j++) {
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
string tok2 = dogs(k2);
k2 = 0;
for (int i = 1; i < tok2.size(); i++)
k2 = k2 * 2 + tok2[i] - '0';
string now;
int k22 = k2;
for (int p = 1; p <= k; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (!check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
// cout << "to " << j << ' ' << k2 << '\n';
}
}
}
s[i] = 'B';
if (i <= k) {
for (int j = 0; j < (1ll << k); j++)
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
// 从k1转移到k2
// cout << "to " << k1 << ' ' << k2 << '\n';
string now;
int k22 = k2;
for (int p = 1; p <= i; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (i < k || !check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
}
} else {
for (int j = 0; j < (1ll << k); j++) {
if (f[i - 1][j]) {
int k1 = j, k2 = j * 2 + s[i] - 'A';
string tok2 = dogs(k2);
k2 = 0;
for (int i = 1; i < tok2.size(); i++)
k2 = k2 * 2 + tok2[i] - '0';
// cout << "dbg " << i << ' ' << j << ' ' << k1 << ' ' << k2 << '\n';
string now;
int k22 = k2;
for (int p = 1; p <= k; p++) {
now = now + (char)(k22 % 2 + 'A');
k22 /= 2;
}
if (!check(now))
f[i][k2] = (f[i][k2] + f[i - 1][k1]) % mod;
}
}
}
s[i] = '?';
}
// cout << "dbg : ";
// for (int j = 0; j < (1ll << k); j++) cout << f[i][j] << ' ';
// cout << '\n';
}
int ss = 0;
for (int i = 0; i < (1ll << k); i++)
ss = (ss + f[n][i]) % mod;
cout << ss << '\n';
return 0;
}
E
令
/*
所有左边比她严格小的棍子隔开的格子都得灌满水才行
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 500100, mod = 998244353;
int a[N], h[N], id[N];
int f[N][20];
int lg[N],n,m;
void init(){
lg[0]=-1;
for(int i=1;i<=n;i++)
lg[i]=lg[i>>1]+1,f[i][0]=h[i];
for(int j=1;j<20;j++)
for(int i=1;i<=n-(1<<j)+1;i++)
f[i][j]=max(f[i+(1<<(j-1))][j-1],f[i][j-1]);
}
int query(int l,int r){
if(l>r)
return 0;
int len=r-l+1,k=lg[len];
return max(f[l][k],f[r-(1<<k)+1][k]);
}
struct Node {
int l, r, sum, tag;
void init(int p) {
l = r = p;
tag = 0, sum = 0;
}
void co(int x) {
sum = (r - l + 1) * x;
tag = x;
}
} z[N << 2];
Node operator+(const Node &l, const Node &r) {
Node res;
res.l = l.l, res.r = r.r;
res.sum = l.sum + r.sum, res.tag = 0;
return res;
}
void build(int l, int r, int rt) {
if (l == r) return z[rt].init(l);
int mid = l + r >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
void pud(int rt) {
if (z[rt].tag) {
z[rt << 1].co(z[rt].tag);
z[rt << 1 | 1].co(z[rt].tag);
z[rt].tag = 0;
}
}
void modify(int l, int r, int rt, int ll, int rr, int v) {
if (ll <= l && r <= rr) return z[rt].co(v);
int mid = l + r >> 1; pud(rt);
if (ll <= mid) modify(l, mid, rt << 1, ll, rr, v);
if (mid < rr) modify(mid + 1, r, rt << 1 | 1, ll, rr, v);
z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
signed main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> h[i];
id[1] = 1;
init();
for (int i = 2; i <= n + 1; i++) {
int l = 1, r = i - 1, best = i;
while (l <= r) {
int mid = l + r >> 1;
if (h[i] >= query(mid, i))
best = mid, r = mid - 1;
else
l = mid + 1;
}
id[i] = best;
}
// cout << "dbg ";
// for (int i = 1; i <= n + 1; i++) cout << id[i] << ' ';
// cout << '\n';
// id[i] 表示 i 想要灌水最左边需要加水的格子是哪一个
build(1, n + 1, 1);
for (int i = 1; i <= n; i++) {
modify(1, n + 1, 1, id[i], i, h[i]);
cout << 1 + z[1].sum << ' ';
}
cout << '\n';
return 0;
}
G
沿用 CF176E(希望我没有记错题号)的思路,对于每一个不同的颜色建立虚树来维护,则问题转化为求树上任意两点之间简单路径的长度之和。这是平凡的。其实也可以使用点分治来维护,但是忘记了点分治怎么写了。但是还有各种其他神秘做法。研究懂了再补充。
代码还没调完,其实是因为赛时没写完然后懒得调了。
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18262823,谢谢QwQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧