• BestCoder Round #74 (div.2)


    组合 1001 LCP Array

    第一题就小难,出题的好像是浙大的大牛?

    找到一个规律:a[i] = x, s[i..i+x]都想同。a[i] = a[i+1] + 1 (a[i] > 0),否则就是与后一个颜色不同,方案*25。第一次颜色相同的26种方案。

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 1e5 + 5;
    const int MOD = 1e9 + 7;
    int a[N];
    
    int main() {
        int T; scanf ("%d", &T);
        while (T--) {
            int n; scanf ("%d", &n);
            for (int i=1; i<n; ++i) {
                scanf ("%d", a+i);
            }
            a[n] = 0;
            int ans = 26;
            for (int i=n-1; i>=1; --i) {
                if (a[i] == 0) {
                    ans = 1ll * ans * 25 % MOD;
                } else if (a[i] != a[i+1] + 1) {
                    ans = 0;
                    break;
                }
            }
            printf ("%d
    ", ans);
        }
    
        return 0;
    }
    

    最短路 1002 Shortest Path

    多加了3条边,6个点分别看成起点跑SPFA,然后原来的距离是abs (u - v),取最小值

    #include <bits/stdc++.h>
    
    const int N = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    int a[6], d[6][N], z[N];
    bool vis[N];
    std::vector<int> G[N];
    int n, m;
    
    void add_edge(int u, int v) {
        G[u].push_back (v);
        G[v].push_back (u);
    }
    
    void SPFA(int k, int s) {
        memset (d[k], INF, sizeof (d[k]));
        memset (vis, false, sizeof (vis));
        d[k][s] = 0; vis[s] = true;
        std::queue<int> que; que.push (s);
        while (!que.empty ()) {
            int u = que.front (); que.pop ();
            for (auto v: G[u]) {
                if (vis[v]) continue;
                d[k][v] = d[k][u] + 1;
                vis[v] = true;
                que.push (v);
            }
        }
    }
    
    int main() {
        int T; scanf ("%d", &T);
        while (T--) {
            scanf ("%d%d", &n, &m);
            for (int i=1; i<=n; ++i) {
                G[i].clear ();
            }
            for (int i=1; i<n; ++i) {
                add_edge (i, i+1);
            }
            for (int i=0; i<3; ++i) {
                int u, v; scanf ("%d%d", &u, &v);
                add_edge (u, v);
                a[i*2] = u; a[i*2+1] = v;
            }
            for (int i=0; i<6; ++i) {
                SPFA (i, a[i]);
            }
            for (int i=0; i<m; ++i) {
                int u, v; scanf ("%d%d", &u, &v);
                if (u > v) std::swap (u, v);
                int &best = z[i];
                best = v - u;
                for (int i=0; i<6; ++i) {
                    best = std::min (best, d[i][u] + d[i][v]);
                }
            }
            int ans = 0;
            for (int i=0; i<m; ++i) {
                ans = (ans + 1ll * (i + 1) * z[i]) % MOD;
            }
            printf ("%d
    ", ans);
        }
    
        return 0;
    }
    

    二进制 + BFS 1003 Transform

    s -> t = s ^ t = x,所以要预处理出0到x的最小步骤,翻转某一位可以转换为^ (1<<i)

    #include <bits/stdc++.h>
    
    const int N = 30;
    const int MAX = (1 << 17);
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    int a[N], d[MAX];
    bool vis[N];
    int n, m;
    
    void BFS(int s) {
        std::queue<int> que; que.push (s);
        memset (d, INF, sizeof (d)); d[s] = 0;
        while (!que.empty ()) {
            int x = que.front (); que.pop ();
            for (int i=1; i<=n; ++i) {
                int y = x ^ a[i];
                if (y > MAX) break;
                if (d[y] < INF) continue;
                d[y] = d[x] + 1;
                que.push (y);
            }
        }
    }
    
    int main() {
        int T; scanf ("%d", &T);
        while (T--) {
            scanf ("%d%d", &n, &m);
            a[0] = 0;
            for (int i=1; i<=n; ++i) {
                scanf ("%d", a+i);
            }
            int k = 0;
            for (int k=0; k<100; ++k) {
                int x = 1 << k;
                if (x > MAX) break;
                a[++n] = x;
            }
            BFS (0);
            int ans = 0;
            for (int i=0; i<m; ++i) {
                int s, t; scanf ("%d%d", &s, &t);
                int q = s ^ t;
                ans = (ans + 1ll * (i + 1) * d[q]) % MOD;
            }
            printf ("%d
    ", ans);
        }
    
        return 0;
    }
    

    1004 Toposort

    待补

  • 相关阅读:
    【SDOI2014】数表
    【洛谷P4735】最大异或和
    FFT学习笔记
    【SHOI2008】堵塞的交通
    HDU 1754 I Hate It 线段树
    hdu 1166 敌兵布阵 ( 线段树或者树状数组)
    hdu 5339 Untitled dfs
    The mook jong
    hdu 5363 Key Set 快速幂
    HDU 1983 Kaitou Kid
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5287686.html
Copyright © 2020-2023  润新知