zoukankan      html  css  js  c++  java
  • Codeforces 600 E

    E - Lomsat gelral

    思路1:

    树上启发式合并

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pii pair<int, int>
    #define piii pair<int,pii>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
    
    const int N = 1e5 + 5;
    int color[N], sz[N], bs[N], mx = 0;
    LL ans[N], t = 0;
    vector<int>g[N];
    map<int, int>mp;
    void dfs(int o, int u) {
        sz[u] = 1;
        for (int v : g[u]) {
            if(v != o) {
                dfs(u, v);
                sz[u] += sz[v];
                if(sz[v] > sz[bs[u]]) bs[u] = v;
            }
        }
    }
    void ADD(int o, int u) {
        mp[color[u]] ++;
        if(mp[color[u]] > mx) t = color[u], mx = mp[color[u]];
        else if(mp[color[u]] == mx) t += color[u];
        for (int v : g[u]) {
            if(v != o) {
                ADD(u, v);
            }
        }
    }
    void DFS(int o, int u) {
        for (int v : g[u]) {
            if(v != o && v != bs[u]) {
                DFS(u, v);
                mp.clear();
                mx = 0;
                t = 0;
            }
        }
        if(bs[u]) DFS(u, bs[u]);
        for (int v : g[u]) {
            if(v != o && v != bs[u]) {
                ADD(u, v);
            }
        }
        mp[color[u]] ++;
        if(mp[color[u]] > mx) t = color[u], mx = mp[color[u]];
        else if(mp[color[u]] == mx) t += color[u];
        ans[u] = t;
    }
    int main() {
        int n, u, v;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &color[i]);
        for (int i = 1; i < n; i++) {
            scanf("%d %d", &u, &v);
            g[u].pb(v);
            g[v].pb(u);
        }
        dfs(0, 1);
        DFS(0, 1);
        for (int i = 1; i <= n; i++) printf("%lld%c", ans[i], " 
    "[i==n]);
        return 0;
    }

     思路2:

    dfs序+分块 求区间众数和

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    //#define mp make_pair
    #define pb push_back
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
    //head
    
    const int N = 1e5 + 10;
    const int M = 500;
    vector<int> g[N];
    vector<int> pos[N];
    int a[N], t[N], in[N], out[N], cnt[N], bl[N], blo, tot = 0, n;
    int f[M][M];
    LL fres[M][M];
    void dfs(int o, int u) {
        in[u] = ++tot;
        t[tot] = a[u];
        for (int v : g[u]) {
            if(v != o) {
                dfs(u, v);
            }
        }
        out[u] = tot;
    }
    void init(int x) {
        for (int i = 1; i <= n; i++) cnt[i] = 0;
        int ans = 0, c = 0;
        LL res = 0;
        for (int  i = (x-1)*blo + 1; i <= n; i++) {
            cnt[t[i]]++;
            if(cnt[t[i]] > c) {
                res = ans = t[i];
                c = cnt[t[i]];
            }
            else if(cnt[t[i]] == c) {
                ans = t[i];
                res += t[i];
            }
            f[x][bl[i]] = ans;
            fres[x][bl[i]] = res;
        }
    }
    int cal(int l, int r, int x) {
        if(l > r) return 0;
        return upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    }
    LL query(int l, int r) {
        LL res = 0;
        int ans = 0, c = 0;
        if(bl[l] == bl[r]) {
            vector<int> vc;
            for (int i = l; i <= r; i++) vc.pb(t[i]);
            sort(vc.begin(), vc.end());
            vc.erase(unique(vc.begin(), vc.end()), vc.end());
            for (int i = 0; i < vc.size(); i++) {
                int tot = cal(l, r, vc[i]);
                if(tot > c) {
                    res = ans = vc[i];
                    c = tot;
                }
                else if(tot == c) {
                    ans = vc[i];
                    res += vc[i];
                }
            }
            return res;
        }
        ans = f[bl[l]+1][bl[r]-1];
        res = fres[bl[l]+1][bl[r]-1];
        int L = bl[l]*blo+1, R = (bl[r]-1)*blo;
        c = cal(L, R, ans);
        vector<int> vc;
        for (int i = l; i <= bl[l]*blo; i++) vc.pb(t[i]);
        for (int i = (bl[r]-1)*blo + 1; i <= r; i++) vc.pb(t[i]);
        sort(vc.begin(), vc.end());
        vc.erase(unique(vc.begin(), vc.end()), vc.end());
        for (int i = 0; i < vc.size(); i++) {
            int tot = cal(l, r, vc[i]);
            if(tot > c) {
                res = ans = vc[i];
                c = tot;
            }
            else if(tot == c) {
                ans = vc[i];
                res += vc[i];
            }
        }
        return res;
    }
    int main() {
        int u, v;
        scanf("%d", &n);
        blo = sqrt(n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for (int i = 1; i < n; i++) {
            scanf("%d %d", &u, &v);
            g[u].pb(v);
            g[v].pb(u);
        }
        dfs(1, 1);
        for (int i = 1; i <= n; i++) bl[i] = (i-1)/blo + 1;
        for (int i = 1; i <= bl[n]; i++) init(i);
        for (int i = 1; i <= n; i++) pos[t[i]].pb(i);
        for (int i = 1; i <= n; i++) printf("%lld%c", query(in[i], out[i]), " 
    "[i==n]);
        return 0;
    }
  • 相关阅读:
    禁止页面缓存 移动端
    常见的请求头与响应头介绍
    阮一峰 ES6学习
    禁止页面缩放 移动端
    10月30日学习日志
    11月7日学习日志
    11月6日学习日志
    10月31日学习日志
    11月1日学习日志
    11月9日学习日志
  • 原文地址:https://www.cnblogs.com/widsom/p/9318041.html
Copyright © 2011-2022 走看看