zoukankan      html  css  js  c++  java
  • HDU

    6647

    比赛的时候, 用了一种垃圾树hash,没过去。。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    #define ll long long
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 998244353;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    const ull B = 1000000007;
    
    int n, m, p, id[N];
    int F[N], Finv[N], inv[N];
    int way[N], totway[N];
    ull sz[N];
    ull hsson[N];
    ull hstot[N];
    ull Pow[N];
    ull rnd[N];
    
    int Rt = 1;
    
    int depth[N];
    
    vector<pair<ull, int>> V[N];
    vector<int> G[N];
    
    void dfs(int u, int fa) {
        way[u] = 1;
        hsson[u] = 0;
        sz[u] = 1;
        depth[u] = depth[fa] + 1;
    
        for(int i = 0; i < SZ(G[u]); i++) {
            if(G[u][i] == fa) {
                G[u].erase(G[u].begin() + i);
                break;
            }
        }
    
        for(auto &v : G[u]) {
            dfs(v, u);
            V[u].push_back(mk(hsson[v], v));
            way[u] = 1LL * way[u] * way[v] % mod;
            sz[u] += sz[v];
        }
    
        sort(ALL(V[u]));
        for(auto &t : V[u]) {
            hsson[u] = hsson[u] * Pow[sz[t.se]] + t.fi;
        }
    
        hsson[u] = hsson[u] * B + rnd[sz[u]];
    
        way[u] = 1LL * way[u] * F[SZ(V[u])] % mod;
    
        for(int i = 0, j = 0; i < SZ(V[u]); i = j) {
            while(j < SZ(V[u]) && V[u][j].fi == V[u][i].fi) j++;
            way[u] = 1LL * way[u] * Finv[j - i] % mod;
        }
    }
    
    void dfs2(int u, ull fhs, int fway) {
        int divway = 1;
        int mulway = 1;
        if(u != Rt) {
            V[u].push_back(mk(fhs, 0));
        }
        for(int i = SZ(V[u]) - 1; i > 0; i--) {
            if(V[u][i] < V[u][i - 1]) swap(V[u][i], V[u][i - 1]);
        }
        hstot[u] = 0;
        totway[u] = 1;
        for(auto &t : V[u]) {
            if(t.se) {
                totway[u] = 1LL * totway[u] * way[t.se] % mod;
                hstot[u] = hstot[u] * Pow[sz[t.se]] + t.fi;
            }
            else {
                totway[u] = 1LL * totway[u] * fway % mod;
                hstot[u] = hstot[u] * Pow[n - sz[u]] + t.fi;
            }
        }
    
        totway[u] = 1LL * totway[u] * F[SZ(V[u])] % mod;
        hstot[u] = hstot[u] * B + rnd[n];
    
    
        vector<int> cnt(SZ(V[u]));
    
        for(int i = 0, j = 0; i < SZ(V[u]); i = j) {
            while(j < SZ(V[u]) && V[u][j].fi == V[u][i].fi) j++;
            totway[u] = 1LL * totway[u] * Finv[j - i] % mod;
            divway = 1LL * divway * Finv[j - i] % mod;
            for(int k = i; k < j; k++) {
                cnt[k] = j - i;
            }
        }
    
        mulway = F[SZ(V[u]) - 1];
    
        vector<pair<ull, int>> pre(SZ(V[u]));
        vector<pair<ull, int>> suf(SZ(V[u]));
        vector<int> sufsz(SZ(V[u]) + 1, 0);
    
        ull tmphs = 0;
        int tmpway = 1;
        int tmpsz = 0;
    
        for(int i = 0; i < SZ(V[u]); i++) {
            if(V[u][i].se) {
                tmpway = 1LL * tmpway * way[V[u][i].se] % mod;
                tmphs = tmphs * Pow[sz[V[u][i].se]] + V[u][i].fi;
            }
            else {
                tmpway = 1LL * tmpway * fway % mod;
                tmphs = tmphs * Pow[n - sz[u]] + V[u][i].fi;
            }
            pre[i] = mk(tmphs, tmpway);
        }
    
        tmphs = 0;
        tmpway = 1;
        tmpsz = 0;
    
        for(int i = SZ(V[u]) - 1; i >= 0; i--) {
            if(V[u][i].se) {
                tmpway = 1LL * tmpway * way[V[u][i].se] % mod;
                tmphs += Pow[tmpsz] * V[u][i].fi;
                tmpsz += sz[V[u][i].se];
            }
            else {
                tmpway = 1LL * tmpway * fway % mod;
                tmphs += Pow[tmpsz] * V[u][i].fi;
                tmpsz += n - sz[u];
            }
            suf[i] = mk(tmphs, tmpway);
            sufsz[i] = tmpsz;
        }
    
        for(int i = 0; i < SZ(V[u]); i++) {
            if(V[u][i].se == 0) continue;
            tmphs = 0, tmpway = 1;
            if(i + 1 < SZ(V[u])) {
                tmphs = suf[i + 1].fi;
                tmpway = 1LL * tmpway * suf[i + 1].se % mod;
            }
            if(i) {
                tmphs += pre[i - 1].fi * Pow[sufsz[i + 1]];
                tmpway = 1LL * tmpway * pre[i - 1].se % mod;
            }
            tmphs = tmphs * B + rnd[n - sz[V[u][i].se]];
            tmpway = 1LL * tmpway * mulway % mod;
            tmpway = 1LL * tmpway * divway % mod;
            tmpway = 1LL * tmpway * F[cnt[i]] % mod;
            tmpway = 1LL * tmpway * Finv[cnt[i] - 1] % mod;
            dfs2(V[u][i].se, tmphs, tmpway);
        }
    }
    
    void init() {
        for(int i = 1; i <= n; i++) {
            G[i].clear();
            V[i].clear();
        }
    }
    
    int main() {
        F[0] = Finv[0] = inv[1] = Pow[0] = 1;
        for(int i = 1; i < N; i++) {
            Pow[i] = Pow[i - 1] * B;
        }
        for(int i = 2; i < N; i++) {
            inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
        }
        for(int i = 1; i < N; i++) {
            F[i] = 1LL * F[i - 1] * i % mod;
        }
        for(int i = 1; i < N; i++) {
            Finv[i] = 1LL * Finv[i - 1] * inv[i] % mod;
        }
        for(int i = 1; i < N; i++) {
            rnd[i] = rng();
        }
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            init();
            for(int i = 1; i <= n; i++) {
                id[i] = i;
            }
            for(int i = 1; i < n; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
    
            dfs(Rt, 0);
            dfs2(Rt, 0, 1);
    
            sort(id + 1, id + 1 + n, [&](int A, int B) {
                return hstot[A] < hstot[B];
            });
    
            int ans = 0;
            for(int i = 1; i <= n; i++) {
                if(i == 1 || hstot[id[i]] != hstot[id[i - 1]]) {
                    add(ans, totway[id[i]]);
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    ##MySql数据库表的操作与应用
    ##如何根据一个端口号,建立BS架构,在网页中打开我们要想的网站
    ##MySql数据库的增删改查方法
    ##MySql数据库的环境配置
    ##安装MySql数据库并解决如果安装出错卸载的注意事项
    ##什么是MySql数据库?它的基本用法
    ##网络编程的优化:如何利用线程优化服务端和客户端
    #XML
    ##如何在IDea中创建一个mxl文件模板
    Java多层嵌套异常处理的基本流程
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11347871.html
Copyright © 2011-2022 走看看