zoukankan      html  css  js  c++  java
  • H 叁佰爱抠的序列(思维欧拉回路)

    题:https://ac.nowcoder.com/acm/contest/4010/H

    题意:找到最大的m,使得存在一个长度为n值域为 [1,m] 的序列,满足任意一组相邻关系都存在。输出为若n>2e6则直接输出m,否则另外输出构造的序列
    分析:相邻关系都要有,那么我们可以联想到n^2的大概样子,然后就m个点完全图可以满足含有相邻关系,更有如果考虑最优,那么存在欧拉回路即可满足条件;

       因为m对于此题来说具有单调性,所以二分地考虑它,m为奇数时,每个点的度数为偶数,必定存在欧拉回路,,m为偶数时,我们利用让含欧拉回路图的性质俩个节点度数为奇数,其余为偶数,方法就是,俩个奇数度数节点连一条边即可;

       最后不足n的部分随便补数即可;

    trick:由于欧拉回路是走边的且要回到起点,所以二分时应该对check部分加1

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<unordered_map>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int M=2e6+6;
    struct node{
        int v,nextt,w;
    }e[M<<1];
    int head[M],tot;
    vector<int>ans;
    void addedge(int u,int v){
        e[tot].v=v;
        e[tot].nextt=head[u];
        e[tot].w=0;
        head[u]=tot++;
        e[tot].v=u;
        e[tot].nextt=head[v];
        e[tot].w=0;
        head[v]=tot++;
    }
    ll check(int x){
        if(x%2)
            return 1ll*x*(x-1)/2+1;///n是走的边,最后返回要边数加1
        else
            return 1ll*x*(x-1)/2+(x-2)/2+1;///同理加1
    }
    void dfs(int u){
        for(int &i=head[u];~i;i=e[i].nextt){
            if(e[i].w==1)
                continue;
            e[i].w=e[i^1].w=1;
            dfs(e[i].v);
        }
        ans.pb(u);
    }
    int main(){
        ll n;
        scanf("%lld",&n);
        ll l=1,r=2e9;
        int m;
        while(l<=r){
            int midd=(l+r)>>1;
            if(check(midd)<=n)
                m=midd,l=midd+1;
            else
                r=midd-1;
        }
        if(n>2e6){
            return printf("%d
    ",m),0;
        }
        for(int i=0;i<=m;i++)
            head[i]=-1;
        for(int i=1;i<=m;i++)
            for(int j=i+1;j<=m;j++)
                addedge(i,j);
        if(m%2==0){
            for(int i=3;i<=m;i+=2)
                addedge(i,i+1);
        }
        dfs(1);
        for(int i=ans.size();i<=n;i++)
            ans.pb(1);
        printf("%d
    ",m);
        for(int i=0;i<n;i++)
            if(i!=n-1) printf("%d ",ans[i]);
            else printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    防火墙透明模式
    HP管理工具System Management Homepage安装配置
    kbmmw 中JSON 中使用SQL 查询
    kbmmw 中JSON 操作入门
    第一个kbmmw for Linux 服务器
    kbmmw 5.02发布
    kbmmw 5.01 发布
    使用delphi 10.2 开发linux 上的Daemon
    使用unidac 在linux 上无驱动直接访问MS SQL SERVER
    使用delphi 10.2 开发linux 上的webservice
  • 原文地址:https://www.cnblogs.com/starve/p/12927240.html
Copyright © 2011-2022 走看看