• luoguP5068 [Ynoi2015]我回来了


    https://www.luogu.org/problemnew/show/P5068

    ynoi 中的良心题啊

    考虑用 bitset 来维护里一个点距离小于 $ y_i $ 的点,那么答案就是一堆 bitset 或起来后二进制位中 $ 1 $ 的个数

    这样我们只要令 $ f[i][j] $ 表示距离 $ i $ 点距离小于 $ j $ 的点,便可以高效求出答案

    考虑怎么求出所有的 $ f[i][j] $

    先枚举起点 $ u $,因为边权为 $ 1 $,所以只需要做一次 bfs

    对于 $ i $ 这个点,假设它到 $ u $ 的距离为 $ dis_i $,那么我们就将 $ f[u][dis_i] $ 的第 $ i $ 位设为 $ 1 $,最后从小到大把 $ f[u][j] $ 或上 $ f[u][j - 1] $ 即可

    复杂度是 $ frac{n^3}{64} + (sumlimits_{i=1}^{q}a_i)*frac{n}{64} $,可以通过此题

    最后 % 一发 lxl

    #include <bits/stdc++.h>
    #define CIOS ios::sync_with_stdio(false);
    #define rep(i, a, b) for(register int i = a; i <= b; i++)
    #define per(i, a, b) for(register int i = a; i >= b; i--)
    #define DEBUG(x) cerr << "DEBUG" << x << " >>> ";
    using namespace std;
    
    typedef unsigned long long ull;
    typedef long long ll;
    
    template <typename T>
    inline void read(T &f) {
        f = 0; T fu = 1; char c = getchar();
        while (c < '0' || c > '9') { if (c == '-') fu = -1; c = getchar(); }
        while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
        f *= fu;
    }
    
    template <typename T>
    void print(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x < 10) putchar(x + 48);
        else print(x / 10), putchar(x % 10 + 48);
    }
    
    template <typename T>
    void print(T x, char t) {
        print(x); putchar(t);
    }
    
    const int N = 1005, INF = 0x7f7f7f7f;
    
    queue <int> q;
    bitset <N> f[N][N], Ans;
    vector <int> adj[N];
    int dis[N][N], n, m, Q, now;
    
    int main() {
        memset(dis, 0x7f, sizeof(dis));
        read(n); read(m); read(Q);
        for(register int i = 1; i <= m; i++) {
            int a, b; read(a); read(b);
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
        for(register int i = 1; i <= n; i++) {
            q.push(i); dis[i][i] = 0; now = i; f[i][0].set(i);
            while(!q.empty()) {
                int u = q.front(); q.pop();
                for(register int j = 0; j < adj[u].size(); j++) {
                    int v = adj[u][j];
                    if(dis[i][v] == INF) {
                        dis[i][v] = dis[i][u] + 1;
                        q.push(v); f[i][dis[i][v]].set(v);
                    }
                }
            }
            for(register int j = 1; j <= n; j++) f[i][j] |= f[i][j - 1];
        }
        while(Q--) {
            int t; read(t); Ans.reset();
            while(t--) {
                int a, b; read(a); read(b);
                if(b > n) b = n;
                Ans |= f[a][b];
            }
            print(Ans.count(), '
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    frog-jump
    nth-digit
    binary-watch
    elimination-game
    evaluate-division
    random-pick-index
    integer-replacement
    rotate-function
    longest-substring-with-at-least-k-repeating-characters
    decode-string
  • 原文地址:https://www.cnblogs.com/LJC00118/p/10098987.html
Copyright © 2020-2023  润新知