zoukankan      html  css  js  c++  java
  • upc2021个人训练赛第23场M: 紫罗兰(dsu)

    问题 M: 紫罗兰

    时间限制: 2 Sec 内存限制: 256 MB

    题目描述
    梦不知何时醒、何时灭,
    纵然天崩地裂,也见不得天日,
    原来都是青天白日下不敢细想的思量……
    那是从来无处表白的,
    那些生不得、死不得、忘不得也记不得的心。
    流年那样无理残忍,稍有踟蹰,它就偷梁换柱,叫人撕心裂肺,再难回头。
    在附中的小路旁种着许多紫罗兰,而我们的问题正是与这些紫罗兰有关。

    我们可以把附中里的道路系统抽象成一棵树,而所有的紫罗兰都被种植在树的节点上,并且每一个节点上的紫罗兰都是同一种品种。我们用一个数字来表示一种品种。同时,我们给每一个节点一个编号,并规定 111 号节点为根节点。每次,Marser 想要知道,以编号为 iii 的节点为根的子树中,出现次数最多,且在此情况下品种编号最小的品种。即意,求出该子树中点权的最小众数。现在,您被要求解决这一问题。
    输入
    第一行一个整数 n,表示树的节点的数量。
    接下来一行 n 个整数 ai,表示每个节点上的品种编号。
    接下来 n−1 行,每行两个整数 s,t,描述树上的一条边。
    接下来一行一个整数 q,表示 Marser 的询问的数量。
    接下来 q 行,每行一个整数 x,表示询问以节点 x 为根的子树中的最小众数。
    输出
    对于每个询问,输出相应的答案。
    样例输入 Copy
    5
    3 2 3 1 3
    1 2
    1 3
    3 4
    3 5
    3
    1
    3
    4
    样例输出 Copy
    3
    3
    1
    提示
    对于100%的数据,保证 n,q≤106 ,1≤ai≤109
    本题输入文件较大,请注意使用读入优化,并采用复杂度较为优秀的做法。

    思路:

    讲解链接
    (dsu)模板题,每次更新答案时都取最小的众数。复杂度(O(nlogn))

    代码:

    // Problem: CF600E Lomsat gelral
    // Contest: Luogu
    // URL: https://www.luogu.com.cn/problem/CF600E
    // Memory Limit: 250 MB
    // Time Limit: 2000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll, ll>PLL;
    typedef pair<int, int>PII;
    typedef pair<double, double>PDD;
    #define I_int ll
    inline ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')f = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
     
    inline void out(ll x){
        if (x < 0) x = ~x + 1, putchar('-');
        if (x > 9) out(x / 10);
        putchar(x % 10 + '0');
    }
     
    inline void write(ll x){
        if (x < 0) x = ~x + 1, putchar('-');
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
        puts("");
    }
     
    #define read read()
    #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
    #define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i<(b);i++)
    #define per(i,a,b) for(int i=(a);i>=(b);i--)
    #define perr(i,a,b) for(int i=(a);i>(b);i--)
    ll ksm(ll a, ll b, ll p)
    {
        ll res = 1;
        while(b)
        {
            if(b & 1)res = res * a % p;
            a = a * a % p;
            b >>= 1;
        }
        return res;
    }
    const int inf = 0x3f3f3f3f;
    #define PI acos(-1)
    const int maxn=1000000+100;
     
    int n,col[maxn];
    vector<int>g[maxn];
    ll ans[maxn],sum;
    int son[maxn],siz[maxn],cnt[maxn],maxx,Son;
     
    void dfs1(int u,int fa){
        siz[u]=1;
        for(int i=0;i<g[u].size();i++){
            int j=g[u][i];
            if(j==fa) continue;
            dfs1(j,u);
            siz[u]+=siz[j];
            if(siz[j]>siz[son[u]]) son[u]=j;
        }
    }
     
    void add(int u,int fa,int val){
        cnt[col[u]]+=val;
        if(cnt[col[u]]>maxx) maxx=cnt[col[u]],sum=col[u];
        else if(cnt[col[u]]==maxx) sum=min(sum,col[u]*1ll);
        for(int i=0;i<g[u].size();i++){
            int j=g[u][i];
            if(j==fa||j==Son) continue;
            add(j,u,val);
        }
    }
     
    void dfs2(int u,int fa,int op){
        for(int i=0;i<g[u].size();i++){
            int j=g[u][i];
            if(j==fa) continue;
            if(j!=son[u]) dfs2(j,u,0);
        }
        if(son[u]) dfs2(son[u],u,1),Son=son[u];
        add(u,fa,1);Son=0;
        ans[u]=sum;
        if(!op) add(u,fa,-1),sum=0,maxx=0;
    }
     
    int main(){
        n=read;
        rep(i,1,n) col[i]=read;
        rep(i,1,n-1){
            int u=read,v=read;
            g[u].push_back(v);
            g[v].push_back(u);
        }   
        dfs1(1,0);
        dfs2(1,0,0);
        int _=read;
        while(_--){
            int x=read;
            printf("%lld
    ",ans[x]);
        }
         
         
        return 0;
    } 
     
     
    
  • 相关阅读:
    NTP on FreeBSD 12.1
    Set proxy server on FreeBSD 12.1
    win32 disk imager使用后u盘容量恢复
    How to install Google Chrome Browser on Kali Linux
    Set NTP Service and timezone on Kali Linux
    Set static IP address and DNS on FreeBSD
    github博客标题显示不了可能是标题包含 特殊符号比如 : (冒号)
    server certificate verification failed. CAfile: none CRLfile: none
    删除文件和目录(彻底的)
    如何在Curl中使用Socks5代理
  • 原文地址:https://www.cnblogs.com/OvOq/p/15049738.html
Copyright © 2011-2022 走看看