Codeforces Round 1030 (Div. 2)

A. Equal Subsequences

全 1 接全 0,两种串的数量都是 0

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;

const int N = 1e5 + 7, mod = 1e9 + 7;

void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) cout << 1;
    for (int i = 0; i < n - m; i++) cout << 0;
    cout << endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

B. Make It Permutation

手玩即可发现,每行固定交换前 i 个和后 n - i 个数即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;

const int N = 1e5 + 7, mod = 1e9 + 7;

struct Node {
    int i, l, r;
};

void solve() {
    int n;
    cin >> n;
    vector<Node> ans;
    for (int i = 1; i <= n; i++) {
        if (i > 1) ans.push_back({i, 1, i});
        if (i + 1 < n) ans.push_back({i, i + 1, n});
    }
    cout << ans.size() << endl;
    for (auto &x : ans) {
        cout << x.i << " " << x.l << " " << x.r << endl;
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

C. Make It Beautiful

按位操作,对输入的每个数的每一位,如果为 1,加入答案,反之则存到一个 Multiset 中,接着对 set 中元素操作,从小到大,用 k 来组成对应的数,看能组成多少个。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;

const int N = 1e5 + 7, mod = 1e9 + 7;

void solve() {
    ll n, k;
    cin >> n >> k;
    int ans = 0;
    multiset<ll> s;
    for (int i = 1; i <= n; i++) {
        ll x;
        cin >> x;
        for (int j = 0; j < 63; j++) {
            if (x & (1ll << j)) {
                ans++;
            } else {
                s.insert(1ll << j);
            }
        }
    }
    for (auto x : s) {
        if (k >= x) {
            ans++;
            k -= x;
        } else break;
    }
    cout << ans << endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

D1. Red Light, Green Light (Easy version)

官方题解的代码直接交上去 wa 了,神人

注意到数据小,可暴力。

DFS 当前位置(只考虑红绿灯的位置),已用时间,方向。

只有 5005002 个状态,足够。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;

const int N = 1e3 + 7, mod = 1e9 + 7;

int vis[N][N][2];
int n, k;
bool flag = 0;
vector<ll> a(N), d(N);

void dfs(int x, ll t, int dir) {
    if (dir == 0) {
        if (x == 1 && (t - d[x]) % k == 0) {
            flag = 1;
            return;
        }
        if(x == n && (t - d[x]) % k != 0) {
            flag = 1;
            return;
        }
        if ((t - d[x]) % k == 0) {
            if (vis[x][t % k][1]) return;
            vis[x][t % k][1] = 1;
            if (x > 1) dfs(x - 1, t + a[x] - a[x - 1], 1);
            // vis[x][t % k][1] = 0;
        } else {
            if (vis[x][t % k][0]) return;
            vis[x][t % k][0] = 1;
            if (x < n) dfs(x + 1, t + a[x + 1] - a[x], 0);
            // vis[x][t % k][0] = 0;
        }
    } else {
        if(x == n && (t - d[x]) % k != 0) {
            flag = 1;
            return;
        }
        if (x == 1 && (t - d[x]) % k != 0) {
            flag = 1;
            return;
        }
        if ((t - d[x]) % k == 0) {
            if (vis[x][t % k][0]) return;
            vis[x][t % k][0] = 1;
            if (x < n) dfs(x + 1, t + a[x + 1] - a[x], 0);
            // vis[x][t % k][0] = 0;
        } else {
            if (vis[x][t % k][1]) return;
            vis[x][t % k][1] = 1;
            if (x > 1) dfs(x - 1, t + a[x] - a[x - 1], 1);
            // vis[x][t % k][1] = 0;
        }
    }
}

void solve() {
    // int n, k;
    cin >> n >> k;
    // vector<ll> a(n + 1), d(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n; i++) {
        cin >> d[i];
    }
    int q;
    cin >> q;
    while (q--) {
        ll pos;
        cin >> pos;
        if(pos > a[n]) {
            cout << "YES\n";
            continue;
        }
        memset(vis, 0, sizeof(vis));
        flag = 0;
        int x = lower_bound(a.begin() + 1, a.begin() + n + 1, pos) - a.begin();
        dfs(x, a[x] - pos, 0);
        cout << (flag ? "YES" : "NO") << endl;
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

D2. Red Light, Green Light (Hard version)

数据大了之后,不能再暴力。

注意到,只能在红灯上转向,且某灯红灯时间对 k 取模后固定。

将遇到某灯且其红灯视为一个状态,只会在这些状态之间跳跃。

问题转化为在这些出度 <= 1 的点构成的有向图之间能否走到边界。

预处理向左向右时,与到某灯,且其红灯的时间。

向右存入前 n 个,向左存入后 n 个,避免覆盖同时方便使用。

接着对这 2 * n 个点判断,如果其有对应状态,赛入其边集合。

某点如果没有对应边,那么其可为出口,用 BFS 找出所有可出去的节点。

开 k 个桶,对应路灯位置模 k 后的状态,对应存入,并将每个桶排序。

回答查询:

先将输入位置模 k,查找桶表中是否存在,如果没有这个桶,说明直接可出去。

否则二分找到对应桶表中其右侧最近的红灯,如果没有,说明其右侧无红灯,也可出。

对找到的红灯判断其是否可出即可

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;

const int N = 1e5 + 7, mod = 1e9 + 7;

void solve() {
    ll n, k;
    cin >> n >> k;
    vector<ll> p(n + 1), d(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
    }
    for (int i = 1; i <= n; i++) {
        cin >> d[i];
    }
    vector<int> to(2 * n + 10, -1);

    unordered_map<ll, int> lst;
    lst.reserve(n * 2 + 10);
    for (int i = 1; i <= n; i++) {
        ll r = (p[i] + d[i]) % k;
        if (auto it = lst.find(r); it != lst.end()) {
            to[i] = it->second + n;
        }
        lst[r] = i;
    }

    lst.clear();
    lst.reserve(n * 2 + 10);
    for (int i = n; i > 0; i--) {
        ll r = (p[i] - d[i]) % k;
        if (r < 0) r += k;
        if (auto it = lst.find(r); it != lst.end()) {
            to[i + n] = it->second;
        }
        lst[r] = i;
    }

    vector<vector<int>> rev(2 * n + 10);
    for (int i = 1; i <= 2 * n; i++) {
        if (to[i] != -1) {
            rev[to[i]].push_back(i);
        }
    }

    vector<int> ans(2 * n + 10, 0);
    deque<int> q;
    for (int i = 1; i <= 2 * n; i++) {
        if (to[i] == -1) {
            ans[i] = 1;
            q.push_back(i);
        }
    } 

    while (!q.empty()) {
        int u = q.front();
        q.pop_front();
        for (auto v : rev[u]) {
            if (!ans[v]) {
                ans[v] = 1;
                q.push_back(v);
            }
        }
    }
    unordered_map<ll, vector<pair<ll, int>>> buc;
    buc.reserve(n * 2 + 10);
    for (int i = 1; i <= n; i++) {
        ll r = (p[i] - d[i]) % k;
        if (r < 0) r += k;
        buc[r].emplace_back(p[i], i);
    }
    for (auto &[_, vec] : buc) {
        sort(vec.begin(), vec.end());
    }
    int qu;
    cin >> qu;
    while (qu--) {
        ll pos;
        cin >> pos;
        ll r = pos % k;
        auto fd = buc.find(r);
        if (fd == buc.end()) {
            cout << "YES" << endl;
            continue;
        }
        const auto &v = fd->second;
        auto it = lower_bound(v.begin(), v.end(), make_pair(pos, -1));
        if (it == v.end()) {
            cout << "YES" << endl;
            continue;
        }
        int idx = it->second;
        cout << (ans[idx] ? "YES" : "NO") << endl;
    }
    
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}
Licensed under CC BY-NC-SA 4.0
最后更新于 Sep 11, 2025 16:27 +0800
发表了95篇文章 · 总计15万2千字
永远相信美好的事情即将发生。
使用 Hugo 构建
主题 StackJimmy 设计