zoukankan      html  css  js  c++  java
  • codeforces 600E dfs+线段树合并

    给你一棵有 n 个点的树

    树上每个节点都有一种颜色 让你求每个点其子树出现最多的颜色,的节点编号

    可以有多个最大值,一起计算.

    裸的线段树合并,边dfs边合并就行了,最后把父亲放进去

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    #define per(ii,a,b) for(int ii=b;ii>=a;--ii)
    #define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mp make_pair
    #define pii pair<ll,ll>
    #define all(x) x.begin(),x.end()
    #define show(x) cout<<#x<<"="<<x<<endl
    #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
    #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
    #define showa(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl
    using namespace std;//head
    const int maxn=1e5+10,maxm=2e6+10;
    const ll INF=0x3f3f3f3f,mod=1e9+7;
    int casn,m,k,n;
    int a[maxn],cnt;
    vector<int> g[maxn];
    int root[maxn];
    ll ans[maxn];
    class dsegtree{public:
    #define nd  node[now]
    #define ndl node[node[now].son[0]]
    #define ndr node[node[now].son[1]]
      struct dsegnode {
        int son[2],cnt,id;
        ll ans;
      }node[maxn*50];
      void pushup(int now){
        if(ndl.cnt>ndr.cnt){
          nd.cnt=ndl.cnt;
          nd.id=ndl.id;
          nd.ans=ndl.ans;
        }else if(ndr.cnt>ndl.cnt){
          nd.cnt=ndr.cnt;
          nd.id=ndr.id;
          nd.ans=ndr.ans;
        }else {
          nd.cnt=ndr.cnt;
          nd.id=ndr.id;
          nd.ans=ndr.ans+ndl.ans;
        }
      }
      void update(int l,int r,int pos,int &now){
        if(!now) now=++cnt;
        if(l==r){
          nd.id=nd.ans=l;
          nd.cnt+=1;
          return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) update(l,mid,pos,nd.son[0]);
        else update(mid+1,r,pos,nd.son[1]);
        pushup(now);
      }
      int merge(int now,int b,int l,int r){
        if(!now||!b) return now^b;
        if(l==r){
          nd.id=nd.ans=l;
          nd.cnt+=node[b].cnt;
          return now;
        }
        nd.son[0]=merge(nd.son[0],node[b].son[0],l,(l+r)/2);
        nd.son[1]=merge(nd.son[1],node[b].son[1],(l+r)/2+1,r);
        pushup(now);
        return now;
      }
    }tree;
    void dfs(int now,int fa){
      for(int to:g[now]){
        if(to==fa) continue;
        dfs(to,now);
        tree.merge(root[now],root[to],1,1e5);
      }
      tree.update(1,1e5,a[now],root[now]);
      ans[now]=tree.node[root[now]].ans;
    }
    int main() {IO;
      cin>>n;
      rep(i,1,n){
         cin>>a[i];
         root[i]=i;
      }
      cnt=n;
      rep(i,2,n){
        int a,b;cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
      }
      dfs(1,0);
      rep(i,1,n) cout<<ans[i]<<' ';
      return 0;
    }
    
  • 相关阅读:
    [No000068]document.body.clientHeight 和 document.documentElement.clientHeight 的区别
    [No000067]Js中获取当前页面的滚动条纵坐标位置scrollTop
    jquery 给a标签绑定click
    java 延时
    MySQL建表语句+添加注释
    ubuntu 搜狗输入法内存占用太多,卡顿不够处理办法
    org.apache.http.client.HttpClient使用方法
    json 文件打读取
    bootStrap @media 用法
    java web项目获取项目路径
  • 原文地址:https://www.cnblogs.com/nervendnig/p/11731962.html
Copyright © 2011-2022 走看看