A. Shout Everyday
将 \(a\) 和 \(b\) 调整成48小时计时法即可
代码实现
a, b, c = map(int, input().split())
if a > b: b += 24
if a <= c <= b:
print('No')
else:
print('Yes')
B. Cut .0
模拟
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
while (s.back() == '0') s.pop_back();
if (s.back() == '.') s.pop_back();
cout << s << '\n';
return 0;
}
C. Enumerate Sequences
暴搜
代码实现
#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;
vector<int> r(n);
rep(i, n) cin >> r[i];
auto f = [&](auto& f, vector<int> a) -> void {
if (a.size() == n) {
int s = 0;
rep(i, n) s += a[i];
if (s%k == 0) {
rep(i, n) cout << a[i] << " \n"[i == n-1];
}
return;
}
int i = a.size();
for (int x = 1; x <= r[i]; ++x) {
vector<int> na = a;
na.push_back(x);
f(f, na);
}
};
f(f, {});
return 0;
}
D. Pedometer
这题实际上是 ABC105D 的环上版本
实际上也简单,也不需要破环成链,注意到假设一段区间 \([l, r]\) 上的累加和为 \(x\),那么区间 \((r, l)\) 上的累加和就是 \(L-x\),其中 \(L = \sum A_i\)
假设 \(S_k = \sum\limits_{i=1}^k A_i\),判断区间 \((r, l)\) 上的累加和是否是 \(M\) 的倍数 \(\Leftrightarrow\) \(L - (S_r - S_{l-1}) \equiv 0 \pmod M\) \(\Leftrightarrow\) \(S_{l-1} \equiv S_r-L \pmod M\)
代码实现
#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, m;
cin >> n >> m;
vector<int> a(n);
rep(i, n) cin >> a[i];
vector<int> s(n+1);
rep(i, n) s[i+1] = (s[i]+a[i])%m;
int L = s[n];
ll ans = 0;
vector<int> cnt(m);
rep(r, n) {
ans += cnt[s[r]];
ans += cnt[(s[r]-L+m)%m];
cnt[s[r]]++;
}
cout << ans << '\n';
return 0;
}
E. Permute K times
考虑对点 \(i\) 到 \(x_i\) 连一条有向边,这样就得到了一个基环树
倍增
记 d[i][v]
表示从点 \(v\) 开始走 \(2^i\) 步到达的点
代码实现
#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; ll k;
cin >> n >> k;
vector<int> x(n), a(n);
rep(i, n) cin >> x[i];
rep(i, n) x[i]--;
rep(i, n) cin >> a[i];
const int D = 60;
vector d(D, vector<int>(n));
d[0] = x;
rep(i, D-1) {
rep(v, n) d[i+1][v] = d[i][d[i][v]];
}
vector<int> ans(n);
rep(i, n) {
int v = i;
rep(j, D) if (k>>j&1) v = d[j][v];
ans[i] = a[v];
}
rep(i, n) cout << ans[i] << ' ';
return 0;
}
F. Rearrange Query
哈希,可以对每种取值赋一个值域比较大的随机数,再取一个大模数即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ull = unsigned long long;
mt19937_64 rng(58);
const ull mod = (1ll<<61)-1; // prime
int main() {
int n, q;
cin >> n >> q;
vector<int> a(n), b(n);
rep(i, n) cin >> a[i];
rep(i, n) cin >> b[i];
const int MX = 200005;
vector<ull> h(MX);
rep(i, MX) h[i] = rng()%mod;
vector<ull> sa(n+1), sb(n+1);
rep(i, n) sa[i+1] = (sa[i]+h[a[i]])%mod;
rep(i, n) sb[i+1] = (sb[i]+h[b[i]])%mod;
rep(qi, q) {
int la, ra, lb, rb;
cin >> la >> ra >> lb >> rb;
--la; --lb;
if ((sa[ra]-sa[la]+mod)%mod == (sb[rb]-sb[lb]+mod)%mod) puts("Yes");
else puts("No");
}
return 0;
}