ATcoder ABC 357 补题记录(A~F)
A
按照顺序直接模拟即可。
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;i++)
#define G(i,x,y) for(int i=x;i>=y;i--)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#ifdef int
#define inf (7611257611378358090ll/2)
#else
#define inf 0x3f3f3f3f
#endif
using namespace std;
const int N = 1000100;
int a[N], n;
signed main() {
int n, m, cnt = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
int h;
cin >> h;
m -= h;
if (m >= 0) {
cnt++;
} else {
break;
}
}
cout << cnt << '\n';
}
B
直接比较大写字母和小写字母的数量即可。
时间复杂度为
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;i++)
#define G(i,x,y) for(int i=x;i>=y;i--)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#ifdef int
#define inf (7611257611378358090ll/2)
#else
#define inf 0x3f3f3f3f
#endif
using namespace std;
const int N = 1000100;
int a[N];
signed main() {
string s;
cin >> s;
int c1 = 0, c2 = 0;
for (auto &x : s) {
if (islower(x)) c1++;
else c2++;
}
if (c1 < c2) {
for (auto &x : s) x = toupper(x);
cout << s << '\n';
} else {
for (auto &x : s) x = tolower(x);
cout << s << '\n';
}
}
C
模拟题。
考虑对于一个
因此直接计算出
时间复杂度为
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;i++)
#define G(i,x,y) for(int i=x;i>=y;i--)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#ifdef int
#define inf (7611257611378358090ll/2)
#else
#define inf 0x3f3f3f3f
#endif
using namespace std;
const int N = 1000100;
int a[N], n;
char s[5999][5999];
void dfs(int n, int x = 1, int y = 1) {
if (n == 0) {
s[x][y] = '#';
} else {
int key = 1;
for (int i = 1; i < n; i++) {
key = key * 3;
}
dfs(n - 1, x, y);
dfs(n - 1, x + key, y);
dfs(n - 1, x + key + key, y);
dfs(n - 1, x, y + key);
dfs(n - 1, x + key + key, y + key);
dfs(n - 1, x, y + key + key);
dfs(n - 1, x + key, y + key + key);
dfs(n - 1, x + key + key, y + key + key);
}
}
signed main() {
cin >> n;
if (!n) {
cout << "#\n";
} else {
int key = 1;
for (int i = 0; i < n; i++) {
key *= 3;
}
for (int i = 1; i <= key; i++) {
for (int j = 1; j <= key; j++) {
s[i][j] = '.';
}
}
dfs(n);
for (int i = 1; i <= key; i++, cout << '\n') {
for (int j = 1; j <= key; j++) {
cout << s[i][j];
}
}
}
}
D
考虑经典套路。这里重定义 to_string(n).size()
(请使用 C++11 及以上版本)。
首先考虑
问题是
然后考虑计算这个东西。当 __int128
来计算答案。其实也可以使用 atcoder::modint998244353
来计算答案。
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;i++)
#define G(i,x,y) for(int i=x;i>=y;i--)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#ifdef int
#define inf (7611257611378358090ll/2)
#else
#define inf 0x3f3f3f3f
#endif
using namespace std;
const int mod = 998244353;
int ksm(int a, __int128 b, int c) {
if (!b) return 1;
int ans = ksm(a, b / 2, c);
ans = ans * ans % c;
if (b & 1) ans = ans * a % c;
return ans;
}
signed main() {
int n;
cin >> n;
int len = to_string(n).size();
int key = ksm(10, (__int128)(len) * n, mod);
key = (key + mod - 1) % mod;
int ii = ksm((ksm(10, len, mod) + mod - 1) % mod, mod - 2, mod);
// cout << "dbg " << ii << ' ' << key << '\n';
cout << (n % mod) * ii % mod * key % mod << '\n';
}
E
不理解为什么题目保证边数不大于点数。这个题
首先建反图,然后考虑使用 Tarjan 算法将有向图中的每一个强连通分量在新图中缩为一个点,然后剩下一个 DAG 森林考虑搞一下。
设
那么对于每一条
。 。
其中
因为新的图是 DAG 森林,所以每一次从入度为
因为不同的
时间复杂度为
#include<bits/stdc++.h>
#define int long long
#define said(...)
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;++i)
#define G(i,x,y) for(int i=x;i>=y;--i)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#define inf (7611257611378358090ll/2)
using namespace std;
const int N = 500100;
const int mod = 998244353;
stack<int> stk;
vector<int> z[N], scc[N];
int idx, tot, instk[N], dfn[N], low[N], bel[N], cnt[N], dis[N], vis[N], en[N], deg[N];
struct Edg { int u, v; } ed[N];
void dfs(int u) {
dfn[u] = low[u] = ++idx;
stk.push(u), instk[u] = true;
W(z, j, u) {
if (!dfn[j]) {
dfs(j);
low[u] = min(low[u], low[j]);
} else if (instk[j]) {
low[u] = min(low[u], dfn[j]);
}
}
if (dfn[u] == low[u]) {
tot++;
while (stk.top() != u) {
int t = stk.top();
stk.pop(), instk[t] = false;
bel[t] = tot, scc[tot].pb(t);
}
int t = stk.top();
stk.pop(), instk[t] = false;
bel[t] = tot, scc[tot].pb(t);
}
}
int a[N], dp[N], gg[N];
auto main() [[O3]] -> signed {
int n;
cin >> n;
F(i, 1, n) {
int x;
cin >> x;
a[i] = x;
z[i].push_back(x);
}
F(i, 1, n) {
if (!dfn[i]) {
dfs(i);
}
}
F(i, 1, n) {
z[i].clear();
}
F(i, 1, n) {
if (bel[i] != bel[a[i]]) {
deg[bel[i]]++;
z[bel[a[i]]].push_back(bel[i]);
}
}
queue<int> q;
F(i, 1, tot) {
if (!deg[i]) {
q.push(i);
}
gg[i] = scc[i].size();
dp[i] = scc[i].size() * scc[i].size();
}
while (q.size()) {
int f = q.front();
q.pop();
for (auto &g : z[f]) {
gg[g] = (gg[g] + gg[f]) % mod;
dp[g] = (dp[g] + scc[g].size() * gg[f] % mod) % mod;
if (!--deg[g]) {
q.push(g);
}
}
}
cout << accumulate(dp + 1, dp + tot + 1, 0ll) << '\n';
}
F
区间修改区间查询很显然的线段树。
考虑对于线段树的每一个结点维护
首先 push_up
的时候直接将
修改的时候:
- 若当前修改的是
的值,则答案从 变为了 。显然后面的式子为 。所以更新答案的时候直接把 加上 ,总和加上 即可。 - 若当前修改的为
的值,则和 的情况一样, 加上 ,总和加上 即可。
下传标记直接按照 long long
。
#include<bits/stdc++.h>
#define int long long
#define said(...)
#define pb push_back
#define em emplace_back
#define F(i,x,y) for(int i=x;i<=y;++i)
#define G(i,x,y) for(int i=x;i>=y;--i)
#define W(G,i,x) for(auto&i:G[x])
#define W_(G,i,j,x) for(auto&[i,j]:G[x])
#define add(x,y) z[x].em(y)
#define add_(x,y) add(x,y),add(y,x)
#define Add(x,y,d) z[x].em(y,d)
#define Add_(x,y,z) Add(x,y,z),Add(y,x,z);
#define inf (7611257611378358090ll/2)
using namespace std;
const int N = 200100;
const int mod = 998244353;
int a[N], b[N];
struct Node {
int l, r, a, b, taga, tagb, sum;
void init(int p) {
l = r = p;
a = ::a[p];
a %= mod;
b = ::b[p];
b %= mod;
taga = tagb = 0;
sum = a * b % mod;
}
void c1(int v) {
v %= mod;
taga += v, a += (r - l + 1) * v;
sum += v * b; sum %= mod;
taga %= mod, a %= mod;
// sum += b * v;
}
void c2(int v) {
v %= mod;
tagb += v, b += (r - l + 1) * v;
sum += v * a % mod; sum %= mod;
tagb %= mod, b %= mod;
// sum = a * b;
}
} z[N << 2];
Node operator+(const Node &l, const Node &r) {
Node res;
res.l = l.l, res.r = r.r;
res.a = l.a + r.a, res.b = l.b + r.b, res.sum = l.sum + r.sum;
res.a %= mod, res.b %= mod, res.sum %= mod;
res.taga = res.tagb = 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].taga != 0) {
z[rt << 1].c1(z[rt].taga);
z[rt << 1 | 1].c1(z[rt].taga);
z[rt].taga = 0;
}
if (z[rt].tagb != 0) {
z[rt << 1].c2(z[rt].tagb);
z[rt << 1 | 1].c2(z[rt].tagb);
z[rt].tagb = 0;
}
}
void modify1(int l, int r, int rt, int ll, int rr, int v) {
if (ll <= l && r <= rr) {
return z[rt].c1(v);
}
int mid = l + r >> 1;
pud(rt);
if (ll <= mid) {
modify1(l, mid, rt << 1, ll, rr, v);
}
if (mid < rr) {
modify1(mid + 1, r, rt << 1 | 1, ll, rr, v);
}
z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
void modify2(int l, int r, int rt, int ll, int rr, int v) {
if (ll <= l && r <= rr) {
return z[rt].c2(v);
}
int mid = l + r >> 1;
pud(rt);
if (ll <= mid) {
modify2(l, mid, rt << 1, ll, rr, v);
}
if (mid < rr) {
modify2(mid + 1, r, rt << 1 | 1, ll, rr, v);
}
z[rt] = z[rt << 1] + z[rt << 1 | 1];
}
int query(int l, int r, int rt, int ll, int rr, int v) {
if (ll <= l && r <= rr) {
return z[rt].sum;
}
int mid = l + r >> 1;
pud(rt);
int s = 0;
if (ll <= mid) {
s = (s + query(l, mid, rt << 1, ll, rr, v)) % mod;
}
if (mid < rr) {
s = (s + query(mid + 1, r, rt << 1 | 1, ll, rr, v)) % mod;
}
return s % mod;
}
auto main() [[O3]] -> signed {
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
build(1, n, 1);
while (q--) {
int o, l, r, x;
cin >> o >> l >> r;
if (o < 3) {
cin >> x;
}
if (o == 1) {
modify1(1, n, 1, l, r, x);
} else if (o == 2) {
modify2(1, n, 1, l, r, x);
} else {
cout << query(1, n, 1, l, r, x) << '\n';
}
}
}
G
咕咕咕。
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18239046,谢谢QwQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧