zoukankan      html  css  js  c++  java
  • [CF888G]Xor-MST

    https://www.zybuluo.com/ysner/note/1253739

    题面

    给定一个(n)个节点的完全图,每个节点有个编号(a_i),节点(i)和节点(j)之间边的权值为(a_iigoplus a_j),求该图的最小生成树的权值和。

    • (nleq2*10^5)

    解析

    有个新奇的最小生成树算法:
    (Boruvka)算法:
    先对于每个点,选择在所有与之相连的边中,权值最小的边,并将这条边加入到最小生成树中。
    显然这样连出来的边会形成一个森林,并且连边后连通块个数至少减半。
    然后我们将每个连通块再看成一个点,重复以上算法即可。
    时间复杂度(O(mlogn))

    从高位往低位贪心。
    把所有点按当前位为(0)还是(1)分为两类。
    显然这两类内部会形成联通块。

    然后这两类间一定会有连边。
    根据上面那个算法,如果我们选出两类数之间边权最小的那条边,这条边一定在最小生成树中。
    因为这是当前状态下(两个大连通块)运行(B)算法后将得到的结果。
    接下来分治对两类数内部进行处理。

    找边权最小值,直接(Trie)树即可。

    总复杂度(O(mlogn))

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #define re register
    #define il inline
    #define ll long long
    #define pb push_back
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int mod=1e9+7,N=2e5+100;
    int n,tot,rt,t[N<<5][2];
    il ll gi()
    {
       re ll x=0,t=1;
       re char ch=getchar();
       while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
       if(ch=='-') t=-1,ch=getchar();
       while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
       return x*t;
    }
    il void Insert(re int &u,re int x,re int d)
    {
      if(!u) u=++tot,t[u][0]=t[u][1]=0;
      if(d<0) return;
      Insert(t[u][(x>>d)&1],x,d-1);
    }
    il int Query(re int u,re int x,re int d)
    {
      if(d<0) return 0;re int c=(x>>d)&1;
      if(t[u][c]) return Query(t[u][c],x,d-1);
      if(t[u][c^1]) return Query(t[u][c^1],x,d-1)^(1<<d);
      return 0;
    }
    il ll solve(vector<int>a,re int d)
    {
      if(!a.size()||d<0) return 0;
      vector<int>b[2];re int mn=0;
      for(re int i=0;i<a.size();i++) b[(a[i]>>d)&1].pb(a[i]);
      if(b[0].size()&&b[1].size())
        {
          tot=rt=0;mn=1<<(d+1);
          for(re int i=0;i<b[0].size();i++) Insert(rt,b[0][i],30);
          for(re int i=0;i<b[1].size();i++) mn=min(mn,Query(rt,b[1][i],30));
        }
      return mn+solve(b[0],d-1)+solve(b[1],d-1);
    }
    int main()
    {
      n=gi();vector<int>a;
      fp(i,1,n) a.pb(gi());
      printf("%lld
    ",solve(a,30));
      return 0;
    }
    
  • 相关阅读:
    centos crash debug
    go get Unknown SSL protocol error in connection to gopkg.in
    Tensorflow serving with Kubernetes
    Spring 集成 Swagger UI
    Docker Registry V2 Garbage Collection
    Docker Registry V2 with Nginx
    Zabbix磁盘性能监控
    Zabbix CPU utilization监控参数
    Windows挂载Gluster复制卷
    Redis持久化存储(三)
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9496053.html
Copyright © 2011-2022 走看看