A. Hamming Distance

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int n;
    string s, t;
    cin >> n >> s >> t;
    
    int ans = 0;
    rep(i, n) ans += s[i] != t[i];
    
    cout << ans << '\n';
    
    return 0;
}

B. Ranking with Ties

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int n;
    cin >> n;
    
    vector<int> p(n);
    rep(i, n) cin >> p[i];
    
    vector<int> ans(n, -1);
    int r = 1;
    while (1) {
        int x = -1;
        rep(i, n) {
            if (ans[i] != -1) continue;
            x = max(x, p[i]);
        }
        if (x == -1) break;
        int k = 0;
        rep(i, n) {
            if (p[i] == x) {
                ans[i] = r;
                k++;
            }
        }
        r += k;
    }
    
    rep(i, n) cout << ans[i] << '\n';
    
    return 0;
}

C. Make it Forest

去掉环上的一条边

代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    
    int ans = 0;
    dsu uf(n);
    rep(i, m) {
        int a, b;
        cin >> a >> b;
        --a; --b;
        if (uf.same(a, b)) {
            ans++;
            continue;
        }
        uf.merge(a, b);
    }
    
    cout << ans << '\n';
    
    return 0;
}

D. Switch Seats

原本不相邻的 \(x\) 要变为相邻,只能通过与 \(x\) 的相邻元素之一交换来实现。因此,只需考虑大约 \(2N\) 个相邻配对,然后全部检查一遍即可!

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using P = pair<int, int>;

void solve() {
    int n;
    cin >> n;
    
    int n2 = n*2;
    vector<int> a(n2);
    rep(i, n2) cin >> a[i];
    rep(i, n2) a[i]--;
    
    vector<vector<int>> is(n);
    rep(i, n2) is[a[i]].push_back(i);
    
    set<P> cand;
    rep(i, n2-1) {
        int x = a[i], y = a[i+1];
        if (x > y) swap(x, y);
        if (x == y) continue;
        cand.emplace(x, y);
    }
    
    int ans = 0;
    for (auto [x, y] : cand) {
        int xl = is[x][0], xr = is[x][1];
        int yl = is[y][0], yr = is[y][1];
        if (xl+1 == xr) continue;
        if (yl+1 == yr) continue;
        if (abs(xl-yl) == 1 and abs(xr-yr) == 1) ans++;
    }
    cout << ans << '\n';
}

int main() {
    int t;
    cin >> t;
    
    while (t--) solve();
    
    return 0;
}

E. Replace

可以通过构建一个表示由哪个字符可以转换为哪个字符的图,我们会发现,只有由环组成的连通分量需要先暂时转换为其他字符!对于环的贡献就是环上的边数+1

但还需考虑一种特殊情况,存在环上某个点的入度大于 \(1\) 时,贡献则是环上的边数

比如

3
abc
bab

\(abc \to cbc \to cac \to bab\)

答案是 \(3\)

代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using P = pair<int, int>;

int solve() {
    int n;
    string s, t;
    cin >> n >> s >> t;
    int m = 26;
    
    if (s == t) return 0;
    {
        set<char> st(t.begin(), t.end());
        if (st.size() == m) return -1;
    }
    
    set<P> es;
    rep(i, n) {
        es.emplace(s[i]-'a', t[i]-'a');
    }
    vector<int> inDeg(m), outDeg(m);
    for (auto e : es) {
        outDeg[e.first]++;
        inDeg[e.second]++;
    }
    rep(i, m) if (outDeg[i] > 1) return -1;
    
    int ans = es.size();
    scc_graph g(m);
    for (auto [a, b] : es) {
        g.add_edge(a, b);
        if (a == b) ans--;
    }
    for (auto grp : g.scc()) {
        if (grp.size() >= 2) {
            bool br = false;
            for (int v : grp) if (inDeg[v] > 1) br = true;
            if (!br) ans++;
        }
    }
    
    return ans;
}

int main() {
    cout << solve() << '\n';
    
    return 0;
}

F. Range Power Sum

本题是积的和典型问题!
\(K\) 次方部分看作 \((A_L + \cdots + A_R) \times \cdots \times (A_L + \cdots + A_R)\)
可以理解为从 \(A_L, \cdots, A_R\) 中选 \(K\) 个数的积的和,因此可以通过dp记录已经选了多少个数来解决!

代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using mint = modint998244353;

struct modinv {
  int n; vector<mint> d;
  modinv(): n(2), d({0,1}) {}
  mint operator()(int i) {
    while (n <= i) d.push_back(-d[mint::mod()%n]*(mint::mod()/n)), ++n;
    return d[i];
  }
  mint operator[](int i) const { return d[i];}
} invs;
struct modfact {
  int n; vector<mint> d;
  modfact(): n(2), d({1,1}) {}
  mint operator()(int i) {
    while (n <= i) d.push_back(d.back()*n), ++n;
    return d[i];
  }
  mint operator[](int i) const { return d[i];}
} facts;
struct modfactinv {
  int n; vector<mint> d;
  modfactinv(): n(2), d({1,1}) {}
  mint operator()(int i) {
    while (n <= i) d.push_back(d.back()*invs(n)), ++n;
    return d[i];
  }
  mint operator[](int i) const { return d[i];}
} ifacts;
mint comb(int n, int k) {
  if (n < k || k < 0) return 0;
  return facts(n)*ifacts(k)*ifacts(n-k);
}

int main() {
    int n, k;
    cin >> n >> k;
    
    vector<int> a(n);
    rep(i, n) cin >> a[i];
    
    mint ans;
    vector<mint> dp(k+1);
    rep(i, n) {
        dp[0] += 1;
        vector<mint> old(k+1);
        swap(dp, old);
        
        rep(j, k+1) {
            rep(c, k-j+1) {
                dp[j+c] += old[j] * mint(a[i]).pow(c) * comb(k-j, c);
            } 
        }
        
        ans += dp[k];
    }
    
    cout << ans.val() << '\n';
    
    return 0;
}