A:Cyclic
模拟
代码实现
a, b, c = input()
print(b+c+a, c+a+b)
B:Strawberries
模拟
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, k;
cin >> n >> k;
string s;
cin >> s;
int ans = 0;
rep(i, n-k+1) {
if (s.substr(i, k) == string(k, 'O')) {
ans++;
rep(j, k) s[i+j] = 'X';
}
}
cout << ans << '\n';
return 0;
}
C:Sowing Stones
考虑将点 \(p_x\) 处的石子搬到下一个最近的有石子的位置 \(x\) 处,首先这两个位置之间的点都应该放一颗石子,然后留一颗将剩下的石子都搬到位置 \(x\) 处
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
int main() {
int n, m;
cin >> n >> m;
vector<P> stones(m);
rep(i, m) cin >> stones[i].first;
rep(i, m) cin >> stones[i].second;
ranges::sort(stones);
stones.emplace_back(n+1, 1);
ll ans = 0;
int px = 0;
ll num = 1;
for (auto [x, a] : stones) {
ll L = x-px;
ll carry = num-L;
ans += (L-1)*L/2;
ans += L*carry;
if (carry < 0) {
puts("-1");
return 0;
}
px = x;
num = carry+a;
}
if (num != 1) puts("-1");
else cout << ans << '\n';
return 0;
}
D:Home Garden
可以开一个变量 now
来记录到目前为止的 \(\sum T\),然后用队列来模拟即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int Q;
cin >> Q;
queue<ll> q;
ll now = 0;
rep(Qi, Q) {
int type;
cin >> type;
if (type == 1) q.push(now);
if (type == 2) {
ll t;
cin >> t;
now += t;
}
if (type == 3) {
ll h;
cin >> h;
int ans = 0;
while (q.size() and now-q.front() >= h) {
ans++;
q.pop();
}
cout << ans << '\n';
}
}
return 0;
}
E:Sum of All Substrings
先将 \(S\) 做一下颠倒,也就是左边变成低位,右边变成高位
记 d[i]
表示第 \(i\) 位上的贡献,从后往前更新 \(d[i]\) 的值,\(d[n-1] = S_{n-1} \times 1\),\(d[n-2] = S_{n-1} \times 1 + S_{n-2} \times 2\),\(\cdots\),\(d_0 = S_{n-1} \times 1 + S_{n-2} \times 2 + \cdots + S_{0} \times n\)
然后做一下进位操作即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
string s;
cin >> n >> s;
ranges::reverse(s);
int mx = n+50;
vector<ll> d(mx);
ll sum = 0;
for (int i = n-1; i >= 0; --i) {
sum += (s[i]-'0')*(n-i);
d[i] = sum;
}
rep(i, mx-1) {
d[i+1] += d[i]/10;
d[i] %= 10;
}
while (d.back() == 0) d.pop_back();
ranges::reverse(d);
for (int digit : d) cout << digit;
return 0;
}
F: Buildings 2
先维护一个从右往左看单调递减的栈
然后固定 \(r\),找它对应的每个 \(l\),此时栈中大于等于 \([l+1,r]\) 中的最大的 \(h\) 之后的所有数都是 \(l\) 和 \(r\) 可以看到的
代码实现
#include <bits/stdc++.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
int op(int a, int b) { return max(a, b); }
int e() { return 0; }
int main() {
int n, q;
cin >> n >> q;
vector<int> h(n);
rep(i, n) cin >> h[i];
vector<vector<P>> qs(n);
rep(i, q) {
int l, r;
cin >> l >> r;
--l; --r;
qs[r].emplace_back(l, i);
}
segtree<int, op, e> rmq(h);
vector<int> ans(q);
vector<int> st;
for (int i = n-1; i >= 0; --i) {
for (auto [l, qi] : qs[i]) {
int max_h = rmq.prod(l+1, i+1);
int now = lower_bound(st.begin(), st.end(), max_h, greater<int>()) - st.begin();
ans[qi] = now;
}
while (st.size() and st.back() < h[i]) st.pop_back();
st.push_back(h[i]);
}
rep(i, q) cout << ans[i] << '\n';
return 0;
}
G: Count Grid 3-coloring
对行做状压dp