关于复杂度
查看原帖
关于复杂度
125355
Mihari楼主2021/10/27 18:45

以下写法是 O(mn2)\mathcal O(mn^2) 还是 O(mn)\mathcal O(mn) 的(忽略 map 的复杂度)?似乎是 O(mn)\mathcal O(mn) 的?

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD

namespace Elaina {

#define rep(i, l, r) for (int i = l, i##_end_ = r; i <= i##_end_; ++i)
#define drep(i, l, r) for (int i = l, i##_end_ = r; i >= i##_end_; --i)
#define fi first
#define se second
#define Endl putchar('\n')

    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;

    template<class T> inline T fab(T x) { return x < 0? -x: x; }
    template<class T> inline void getmax(T& x, const T& rhs) { x = max(x, rhs); }
    template<class T> inline void getmin(T& x, const T& rhs) { x = min(x, rhs); }

#ifdef USING_FREAD
# define CHARRECEI qkgetc()
    inline char qkgetc() {
# define BUFFERSIZE 1 << 18
        static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
        return (p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2))? EOF : *p1++;
# undef BUFFERSIZE
    }
#else
# define CHARRECEI getchar()
#endif

    template<class T> inline T readret(T x) {
        x = 0; char c; bool f = false;
        while (!isdigit(c = CHARRECEI)) if (c == '-') f = true;
        for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
        return f? -x: x;
    }
    template<class T> inline void readin(T& x) {
        x = 0; char c; bool f = false;
        while (!isdigit(c = CHARRECEI)) if (c == '-') f = true;
        for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
        if (f) x = -x;
    }
    template<class T, class... Args> inline void readin(T& x, Args&... args) {
        readin(x), readin(args...);
    }
    template<class T> inline void writln(T x, char c = '\n') {
        static int writ_stk[55], writ_ed;
        if (x < 0) putchar('-'), x = -x;
        do writ_stk[++writ_ed] = x % 10, x /= 10; while (x);
        while (writ_ed) putchar(writ_stk[writ_ed--] ^ 48);
        putchar(c);
    }

} // namespace Elaina
using namespace Elaina;

const int maxn = 50;
const int inf = 0x3f3f3f3f;

bool sie[1005];
int prime[1005], pcnt;
inline void sieve() {
    int n = 1000; sie[1] = true;
    for (int i = 2; i <= n; ++i) {
        if(!sie[i]) prime[++pcnt] = i;
        for (int j = 1; j <= pcnt && i * prime[j] <= n; ++j) {
            sie[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
        }
    }
}

vector<int> g[maxn + 5];
inline void add_edge(int u, int v) {
    g[u].push_back(v), g[v].push_back(u);
}

int n, m;

inline void input() {
    readin(n);
    for (int i = 1; i <= n; ++i) g[i].clear();
    int fa;
    for (int i = 1; i <= n; ++i) {
        readin(fa);
        if (fa) add_edge(fa, i);
    }
}

int siz[maxn + 5], mx[maxn + 5], mn;
void dfs1(int u, int par) {
    siz[u] = 0, mx[u] = 0;
    for (int v: g[u]) if(v ^ par) {
        dfs1(v, u), siz[u] += siz[v];
        getmax(mx[u], siz[v]);
    }
    getmax(mx[u], n - siz[u]);
    if(mx[u] < mn) mn = mx[u];
}

ull getHash(int u, int par) {
    ull ans = 1, tmp; siz[u] = 1;
    for (int v: g[u]) if(v ^ par) {
        tmp = getHash(v, u);
        ans += tmp * prime[siz[v]];
        siz[u] += siz[v];
    }
    return ans;
}

map< pair<ull, int>, int > table;

signed main() {
    sieve();
    readin(m);
    for (int _ = 1; _ <= m; ++_) {
        input();
        mn = inf; dfs1(1, 0);
        ull h = ULLONG_MAX;
        for (int u = 1; u <= n; ++u) if (mx[u] == mn)
            getmin(h, getHash(u, 0));
        if (!table.count({h, n})) table[{h, n}] = _;
        writln(table[{h, n}]);
    }
    return 0;
}
2021/10/27 18:45
加载中...