Featured image of post AtCoder Regular Contest 111

AtCoder Regular Contest 111

ARC 111

因為 pA 卡住,所以慘慘的 QAQ

掉了 31 分到 1685。

AtCoder Regular Contest 111

A. Simple Math 2

題意

$$1 \leq n \leq 10^{18}, 1 \leq m \leq 10^4, \text{find }\lfloor \frac{10^n}{m}\rfloor \mod m.$$

解法

  • 求 (10 ** n) % (m * m) // m。
  • 紀錄餘數的循環節。
  • 卡題原因:
    • 忘記循環不一定從一開始。
    • 用了 unordered_map 判斷餘數是否出現過導致 TLE,換成 array 就變很快了。

Code

 1#include<bits/stdc++.h>
 2using namespace std;
 3typedef long long ll;
 4#define pb push_back
 5int s[100000008];
 6int main() {
 7    ll n, m, mm;
 8    cin >> n >> m;
 9    mm = m * m;
10    ll r, d = 1;
11    vector<int> v; // 紀錄餘數
12    for (int i = 0; i <= n; i++) {
13        r = d % mm;
14        if (s[r] || (i && r == v[0])) break;
15        s[r] = i;
16        v.pb(r);
17        d = r * 10;
18    }
19    if (n < v.size()) {
20        cout << v[n] / m << "\n";
21        return 0;
22    }
23    int t = s[r]; // 循環節起點
24    int id = t + (n - t) % (v.size() - t);
25    cout << v[id] / m << '\n';
26    return 0;
27}

B. Reversible Cards

題意

給定 N 張卡(≤2e5),每張卡上正反面各有一個數字(1~4e5),讓你每張牌只能選擇一面,問最多有幾個相異數字?

解法

建立一個 Source,給每張牌 cap = 1 的邊,然後每張牌建立到正反兩面的數字 cap = 1 到邊,每個數字建立到 Sink cap = 1 的邊,之後求最大流 max-flow 即為答案

因為是二分圖,所以用 Dinic 複雜度約為 O(sqrt(V)E) ~ 2e8。

Code

 1#include<bits/stdc++.h>
 2using namespace std;
 3typedef long long ll;
 4typedef pair<int, int> pii;
 5#define pb push_back
 6#define inf 1e9
 7#define maxn 200000
 8#define maxk 400000
 9class Dinic {
10   private:
11    struct edge { int d, r; ll c; };
12    vector<vector<edge>> adj; vector<int> lv, ve; int n;
13    bool mklv(int s, int d) {
14        lv.assign(n, -1); lv[s] = 0; queue<int> q({s});
15        while (!q.empty()) {
16            int v = q.front(); q.pop();
17            for (auto& e : adj[v]) {
18                if (e.c == 0 || lv[e.d] != -1) continue;
19                lv[e.d] = lv[v] + 1, q.push(e.d);
20            }
21        }
22        return lv[d] > 0;
23    }
24    ll aug(int v, ll f, int d) {
25        if (v == d) return f;
26        for (; ve[v] < adj[v].size(); ve[v]++) {
27            auto& e = adj[v][ve[v]];
28            if (lv[e.d] != lv[v] + 1 || !e.c) continue;
29            ll sent = aug(e.d, min(f, e.c), d);
30            if (sent > 0) {
31                e.c -= sent, adj[e.d][e.r].c += sent; 
32                return sent;
33            }
34        } 
35        return 0;
36    }
37   public:
38    Dinic(int n) : n(n + 1) { clear(); }
39    void clear() { adj.assign(n, {}); }
40    void add_edge(int src, int dst, ll cap) {
41        edge ss{dst, (int)adj[dst].size(), cap};
42        edge dd{src, (int)adj[src].size(), 0};
43        adj[src].push_back(ss), adj[dst].push_back(dd);
44    }
45    ll max_flow(int s, int d) {
46        ll ret = 0;
47        while (mklv(s, d)) {
48            ve.assign(n, 0);
49            while (ll f = aug(s, inf, d)) ret += f;
50        } 
51        return ret;
52    }
53};
54int main() {
55    ios::sync_with_stdio(0), cin.tie(0);
56    int n; cin >> n;
57    Dinic D(maxn + maxk + 2);
58    int dst = maxn + maxk + 1;
59    for (int i = 1; i <= n; i++) {
60        int a, b; cin >> a >> b;
61        D.add_edge(0, i, 1);
62        D.add_edge(i, maxn + a, 1);
63        D.add_edge(i, maxn + b, 1);
64    }
65    for (int i = 1; i <= maxk; i++)
66        D.add_edge(maxn + i, dst, 1);
67    cout << D.max_flow(0, dst) << "\n";
68    return 0;
69}
Built with Hugo
Theme Stack designed by Jimmy