• CodeForces 959E Mahmoud and Ehab and the xor-MST (MST+找规律)


    <题目链接>

    题目大意:

    给定一个数n,代表有一个0~n-1的完全图,该图中所有边的边权为两端点的异或值,求这个图的MST的值。

    解题分析:

    数据较大,$10^{12}$个点的完全图,然后异或又暂时推不出什么性质,所以先起手Kruskal打一张小数据完全图的MST的表,发现规律其实还是蛮好找的。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e5+5;
    
    int fa[N],cnt,ncase;
    struct Edge{ int u,v,w; 
        bool operator < (const Edge &tmp)const{
            return w<tmp.w;
        }
    }e[N];
    map<int,int>mpa;
    inline void add(int u,int v,int w){
        e[++cnt]=(Edge){u,v,w};
    }
    inline int find(int &x){
        while(x!=fa[x])
            x=fa[x]=fa[fa[x]];
    }
    inline void Kruskal(){
        sort(e+1,e+1+cnt);    
        for(int i=1;i<=cnt;i++){
            int u=e[i].u,v=e[i].v;
            find(u);find(v);
            if(u!=v){
                fa[v]=u;
                printf("%dth edge , w=%d
    ",++ncase,e[i].w);
                mpa[e[i].w]++;
            } 
        }
        for(auto i:mpa){
            printf("%d have %d (num)
    ",i.first,i.second);
        }
    }
    int main(){
        int n;cin>>n;
        ncase=0;
        for(int i=0;i<n;i++)fa[i]=i;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                add(i,j,i^j);
            }
        }
        Kruskal();
    }
    打表

    然后根据规律就可以快速求解了。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int main(){
        ll n,ans,w=1;
        scanf("%lld",&n);
        while(n>1){
            ans+=w*(n>>1);  //(n>>1)代表边数,w代表权值 
            w<<=1;   
            n-=n>>1;        
        }
        cout<<ans<<endl;    
    }
  • 相关阅读:
    博客园小技巧【转载】
    Windows下的多线程
    【Windows】Windows中的数据类型以及命名
    【文档管理系统】【转】什么是元数据
    CentOS 安装 MariaDB 全部命令
    emacs 入门
    参考路径
    My SQL load data infile 遇到的问题总结
    oracle迁移到mysql(仅使用脚本)
    Eclipse tomcat server 无法添加项目
  • 原文地址:https://www.cnblogs.com/00isok/p/10680388.html
Copyright © 2020-2023  润新知