zoukankan      html  css  js  c++  java
  • Codeforces Round #625 (1A

    A - Journey Planning

    题意: 有一列共 n 个城市, 每个城市有美丽值 b[i], 要访问一个子序列的城市, 这个子序列相邻项的原项数之差等于美丽值之差, 求最大的美丽值总和.

    思路: 对于一个合法的子序列, b[i] - i 结果是一个定值, 统计该值取最大.

    view code
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inc(i, l, r) for (int i = l; i <= r; i++)
    
    const int maxn = 1e6 + 5;
    
    int n, b[maxn];
    
    int main() {
        cin >> n;
        map<int, ll> a;
        inc(i, 0, n - 1) {
            cin >> b[i];
            a[b[i] - i] += b[i];
        }
        ll res = 0;
        for (auto ite : a) res = max(res, ite.second);
        cout << res << "
    ";
    }
    

    B - Navigation System

    题意: 给出一个有向图和一个人的行动路径, 这个人每次移动前导航仪会给出从当前点到终点的一条最短路线, 如果这个人移动的路线与之不符, 导航仪会重新生成从下一个点出发到终点的最短路线. 问导航仪生成新路线的最小和最大次数.

    思路: bfs求出所有点到终点的最短距离. 如果这个人移动时距离终点不是-1, 那他这次移动一定不在最短路线上; 否则, 检查是否有其他使距离-1的路线, 如果有, 那么就知道导航仪可能会重新生成路线.

    view code
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inc(i, l, r) for (int i = l; i <= r; i++)
    
    const int maxn = 1e6 + 5;
    const int inf = 0x3f3f3f3f;
    
    vector<int> g[maxn];
    vector<int> rg[maxn];
    int a[maxn], d[maxn], vis[maxn];
    int n, m, u, v, k;
    
    int main() {
        memset(d, 63, sizeof(d));
        cin >> n >> m;
        inc(i, 1, m) {
            cin >> u >> v;
            rg[u].push_back(v);
            g[v].push_back(u);
        }
        cin >> k;
        inc(i, 1, k) cin >> a[i];
        queue<int> que;
        que.push(a[k]);
        d[a[k]] = 0;
        vis[a[k]] = 1;
        while (que.size()) {
            int p = que.front();
            que.pop();
            inc(i, 0, (int)g[p].size() - 1) {
                if (!vis[g[p][i]]) {
                    d[g[p][i]] = d[p] + 1;
                    que.push(g[p][i]);
                    vis[g[p][i]] = 1;
                }
            }
        }
        int res1 = 0, res2 = 0;
        for (int i = 1; i < k; i++) {
            int now = a[i], nxt = a[i + 1];
            if (d[now] != d[nxt] + 1)
                res1++, res2++;
            else
                inc(j, 0, (int)rg[now].size() - 1) {
                    if (d[rg[now][j]] + 1 == d[now] && rg[now][j] != nxt) {
                        res2++;
                        break;
                    }
                }
        }
        cout << res1 << " " << res2;
    }
    

    C - World of Darkraft: Battle for Azathoth

    题意: 给出 n 个武器, m 个防具, 分别有攻击力 ai 和防御力 bi, 购买该装备需要的金币ci, 还有 p 个怪兽, 分别具有防御力 xi, 攻击力 yi, 打败它获得的金币 ci. 现要求从中武器和防具中各选出恰好一个, 然后就可以打败所有满足 ai > xj 且 bi > yj 的怪兽并获得 cj. 求最大获利.

    思路: 预处理攻击力和防御力达到 x 最少需要支付的金币数 atk[x], def[x]. 对所有怪兽排序(不妨以 xi 为第一关键字), 扫描一遍, 维护这样的线段树: 防御力为 x 时的最大获利, 每个节点初始值为 -def[x], 表示为了该防具需要支付的金币数. 每扫过一只怪兽, 防御力足以打败该怪兽的范围就增加 ci, 而武器攻击力为当前怪兽的 xi + 1, 这样可以确保前面扫描过的怪兽都满足 ai > xj.

    view code
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inc(i, l, r) for (int i = l; i <= r; i++)
    #define dec(i, l, r) for (int i = l; i >= r; i--)
    #define pii pair<int, int>
    #define fi first
    #define se second
    #define pb push_back
    
    const int maxn = 1e6 + 5;
    const int inf = 0x3f3f3f3f;
    
    int n, m, p;
    int atk[maxn], def[maxn];
    struct node {
        int a, b, c;
        bool operator<(const node &o) const {
            if (a == o.a) return b < o.b;
            return a < o.a;
        }
    } mos[maxn];
    int x, y, c, matk, mdef;
    
    ll f[4 * maxn], mv[4 * maxn];
    
    void up(int k) { mv[k] = max(mv[k << 1], mv[k << 1 | 1]); }
    void down(int k) {
        f[k << 1] += f[k], f[k << 1 | 1] += f[k];
        mv[k << 1] += f[k], mv[k << 1 | 1] += f[k];
        f[k] = 0;
    }
    void build(int k, int l, int r) {
        if (l == r) {
            mv[k] = -def[l];
            return;
        }
        int mid = l + r >> 1;
        build(k << 1, l, mid);
        build(k << 1 | 1, mid + 1, r);
        up(k);
    }
    void add(int k, int l, int r, int val, int a, int b) {
        if (a <= l && r <= b) {
            mv[k] += val, f[k] += val;
            return;
        }
        down(k);
        int mid = l + r >> 1;
        if (a <= mid) add(k << 1, l, mid, val, a, b);
        if (b > mid) add(k << 1 | 1, mid + 1, r, val, a, b);
        up(k);
    }
    
    int main() {
        memset(atk, 127, sizeof(atk));
        memset(def, 127, sizeof(def));
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cin >> n >> m >> p;
        inc(i, 1, n) {
            cin >> x >> c;
            atk[x] = min(atk[x], c);
            matk = max(x, matk);
        }
        dec(i, matk - 1, 1) atk[i] = min(atk[i], atk[i + 1]);
        inc(i, 1, m) {
            cin >> x >> c;
            def[x] = min(def[x], c);
            mdef = max(x, mdef);
        }
        dec(i, mdef - 1, 1) def[i] = min(def[i], def[i + 1]);
        build(1, 1, mdef);
        inc(i, 0, p - 1) {
            cin >> x >> y >> c;
            mos[i] = {x, y, c};
        }
        sort(mos, mos + p);
        ll res = -atk[1] - def[1];
        inc(i, 0, p - 1) {
            if (mos[i].b < mdef) add(1, 1, mdef, mos[i].c, mos[i].b + 1, mdef);
            if (mos[i].a < matk) res = max(res, mv[1] - atk[mos[i].a + 1]);
        }
        cout << res;
    }
    

    D - Reachable Strings

    题意: 给出一个串 s, 和 q 组查询, 询问 s 的两个子串是否是 Reachable. 所谓 Reachable 是指将一个串的子串 "011" 变为 "110" 或者把 "110" 变为 "011", 可以变换多次. |s| ≤ 2e5, q ≤ 2e5.
    思路: 这个变换操作的本质就是将 "0" 移动并穿过若干个 "11". 将串 s 中成对相邻的 "1" 都去掉得到串 t, 此时 Reachable 就等价于在 t 中的对应子串一样. 这个可以用 Hash 判断. 注意子串在变换到 t 时左右两边省略掉的 "1" 奇偶性也得一致.

    view code
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inc(i, l, r) for (int i = l; i <= r; i++)
    #define dec(i, l, r) for (int i = l; i >= r; i--)
    
    const int maxn = 2e5 + 5;
    const int mod0 = 1e9 + 7;
    const int mod1 = 1e9 + 9;
    const int BASE = 2;
    
    int n, l1, l2, len, q;
    char s[maxn];
    
    int num[maxn];
    ll hash0[maxn], hash1[maxn];
    ll pow0[maxn], pow1[maxn];
    int l[maxn], r[maxn], pos[maxn];
    
    string t = "#";
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cin >> n >> s + 1 >> q;
        dec(i, n, 1) r[i] = s[i] == '1' ? r[i + 1] + 1 : 0;
        inc(i, 1, n) l[i] = s[i] == '1' ? l[i - 1] + 1 : 0;
        inc(i, 1, n) {
            if (s[i] == '0') {
                pos[i] = t.size();
                t += '0';
            } else if (t.back() == '1') {
                t.pop_back();
            } else {
                t += '1';
            }
        }
        int len = t.size() - 1;
        pow0[0] = pow1[0] = 1;
        inc(i, 1, len) {
            pow0[i] = pow0[i - 1] * BASE % mod0;
            pow1[i] = pow1[i - 1] * BASE % mod1;
            hash0[i] = (hash0[i - 1] * BASE + t[i] - '0') % mod0;
            hash1[i] = (hash1[i - 1] * BASE + t[i] - '0') % mod1;
        }
    
        inc(ca, 1, q) {
            cin >> l1 >> l2 >> len;
            int z1 = l1 + r[l1], y1 = l1 + len - 1 - l[l1 + len - 1];
            int z2 = l2 + r[l2], y2 = l2 + len - 1 - l[l2 + len - 1];
            if (z1 > y1 && z2 > y2) {
                cout << "Yes
    ";
                continue;
            }
            if (z1 > y1 || z2 > y2) {
                cout << "No
    ";
                continue;
            }
            if (r[l1] % 2 != r[l2] % 2 ||
                l[l1 + len - 1] % 2 != l[l2 + len - 1] % 2) {
                cout << "No
    ";
                continue;
            }
    
            z1 = pos[z1] - 1, y1 = pos[y1], z2 = pos[z2] - 1, y2 = pos[y2];
    
            if (y1 - z1 == y2 - z2 &&
                (hash0[y1] + (mod0 - pow0[y1 - z1]) * hash0[z1]) % mod0 ==
                    (hash0[y2] + (mod0 - pow0[y2 - z2]) * hash0[z2]) % mod0 &&
                (hash1[y1] + (mod1 - pow1[y1 - z1]) * hash1[z1]) % mod1 ==
                    (hash1[y2] + (mod1 - pow1[y2 - z2]) * hash1[z2]) % mod1) {
                cout << "Yes
    ";
            } else {
                cout << "No
    ";
            }
        }
    }
    
  • 相关阅读:
    使用JS模拟锚点跳转
    js如何获取url参数
    k64 datasheet学习笔记52---Universal Asynchronous Receiver/Transmitter (UART)
    k64 datasheet学习笔记11---Port Control and Interrupts (PORT)
    k64 datasheet学习笔记10---Signal Multiplexing and Signal Descriptions
    k64 datasheet学习笔记50---GPIO
    k64 datasheet学习笔记4---Clock distribution
    k64 datasheet学习笔记3---Chip Configuration之Human machine interfaces
    k64 datasheet学习笔记3---Chip Configuration之Communication interfaces
    k64 datasheet学习笔记3---Chip Configuration之Times
  • 原文地址:https://www.cnblogs.com/linqi05/p/12391937.html
Copyright © 2011-2022 走看看