T1:321-like Checker

模拟

代码实现
#include <bits/stdc++.h>

using namespace std;

int main() {
    string s;
    cin >> s;
    
    for (int i = 0; i+1 < s.size(); ++i) {
        if (s[i] <= s[i+1]) {
            puts("No");
            return 0;
        } 
    }
    
    puts("Yes");
    
    return 0;
}

T2:Cutoff

暴力枚举 \(A_N\) 即可

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

using namespace std;

int main() {
    int n, x;
    cin >> n >> x;
    
    vector<int> a(n);
    rep(i, n-1) cin >> a[i];
    
    while (a.back() <= 100) {
        auto b = a;
        sort(b.begin(), b.end());
        int s = 0;
        for (int i = 1; i < n-1; ++i) s += b[i];
        if (s >= x) {
            cout << a.back() << '\n';
            return 0;
        }
        a.back()++;
    }
    
    puts("-1");
    
    return 0;
}

T3:321-like Searcher

暴搜出所有的 321-like Number

代码实现
#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 k;
    cin >> k;
    
    vector<ll> a;
    rep(s, 1<<10) {
        ll x = 0;
        for (int i = 9; i >= 0; --i) {
            if (s>>i&1) {
                x = x*10+i;
            }
        }
        if (x == 0) continue;
        a.push_back(x);
    }
    
    sort(a.begin(), a.end());
    
    cout << a[k-1] << '\n';
    
    return 0;
}

T4:Set Menu

\( \displaystyle \sum_{i=1}^N\sum_{j=1}^M \min(A_i+B_j, P) = \sum_{i=1}^N\sum_{j=1}^M (A_i+\min(B_j, P-A_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, m, p;
    cin >> n >> m >> p;
    
    vector<int> a(n), b(m);
    rep(i, n) cin >> a[i];
    rep(i, m) cin >> b[i];
    
    sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    vector<ll> s(m+1);
    rep(i, m) s[i+1] = s[i]+b[i];
    
    ll ans = 0;
    rep(i, n) {
        int j = lower_bound(b.begin(), b.end(), p-a[i])-b.begin();
        ans += 1ll*p*(m-j);
        ans += 1ll*a[i]*j;
        ans += s[j];
    }
    
    cout << ans << '\n';
    
    return 0;
}

T5:Complete Binary Tree

枚举 \(\operatorname{lca}\)

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

using namespace std;
using ll = long long;

void solve() {
    ll n, x, k;
    cin >> n >> x >> k;
    
    auto f = [&](ll v, ll d) -> ll {
        if (v > n) return 0;
        ll l = v, r = v;
        rep(i, d) {
            l <<= 1;
            r = r<<1|1;
            if (l > n) return 0;
        }
        r = min(r, n);
        return r-l+1;
    };
    
    ll ans = f(x, k);
    while (x > 1 and k >= 2) {
        ans += f(x^1, k-2);
        k--; x >>= 1;
    }
    if (k == 1 and x != 1) ans++;
    cout << ans << '\n';
}

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

T6:#(subset sum = K) with Add and Erase

回退背包

代码实现
#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 mint = modint998244353;

int main() {
    int q, k;
    cin >> q >> k;
    
    vector<mint> dp(k+1);
    dp[0] = 1;
    
    rep(qi, q) {
        char c; int x;
        cin >> c >> x;
        if (c == '+') {
            for (int i = k; i >= x; --i) {
                dp[i] += dp[i-x];
            }
        }
        else {
            for (int i = x; i <= k; ++i) {
                dp[i] -= dp[i-x];
            }
        }
        cout << dp[k].val() << '\n';
    }
    
    return 0;
}

T7:Electric Circuit

状压dp+容斥

dp[S] 表示由集合 \(S\) 中的点构成的图中为连通图的方案数

代码实现
#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 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, m;
    cin >> n >> m;
    
    vector c(2, vector<int>(n));
    rep(j, 2) {
        rep(i, m) {
            int v;
            cin >> v;
            --v;
            c[j][v]++;
        }
    }
    
    int n2 = 1<<n;
    vector<mint> d(n2);
    rep(s, n2) {
        vector<int> nc(2);
        rep(i, n) if (s>>i&1) {
            rep(j, 2) nc[j] += c[j][i];
        } 
        if (nc[0] != nc[1]) continue;
        d[s] = facts(nc[0]);
    }
    
    mint ans;
    vector<mint> dp(n2);
    rep(s, n2) if (s) {
        dp[s] = d[s];
        int v = s&-s;
        int ns = s^v;
        for (int t = ns; t; t = (t-1)&ns) {
            dp[s] -= dp[s^t]*d[t];
        }
        
        ans += dp[s]*d[(n2-1)^s];
    }
    ans *= ifacts(m);
    
    cout << ans.val() << '\n';
    
    return 0;
}