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;
}