当前位置: 首页 > news >正文

2020智算之道复赛 C - 有向无环图(思维+二进制拆分)

在这里插入图片描述
首先最重要的一点是要知道图如何去画,以四个点为例,一般也许会画上下左右四个点的图,但是这样的话很难发现规律,实际上因为是有向无环图,那么我们考虑所有节点排成一条链,然后像找任意两点间的连线那样考虑,如下图所示:
在这里插入图片描述
很容易发现以下规律,设 x x x为图的点数, y y y为路径数:

  • x = 2 x=2 x=2时, y = 1 y=1 y=1
  • x = 3 x=3 x=3时, y = 2 y=2 y=2
  • x = 4 x=4 x=4时, y = 4 y=4 y=4
  • x = 5 x=5 x=5时, y = 8 y=8 y=8

那么得到,当图有 x x x个节点时,路径数为 2 x − 2 2^{x-2} 2x2

如果先拿出 x x x个节点,先连成一条链,然后将除一号节点外的所有节点向后面的 x − i − 1 x-i-1 xi1个节点连接,那么路径数为 2 x − 3 2^{x-3} 2x3条,然后我们将一号节点依次连向第 x , x − 1 , x − 2 , . . . , 3 x,x-1,x-2,...,3 x,x1,x2,...,3个节点时,增加的路径数分别为 1 , 1 , 2 , 4 , 8 , . . . 1,1,2,4,8,... 1,1,2,4,8,...,很容易联想到二进制拆分。

假设需要 k k k条路径,先找到大于等于 k k k的第一个 2 2 2的次幂 x x x,那么显然顶点总数为 m = x + 2 m=x+2 m=x+2,然后按上述第一个步骤连接。接下来看看余数是否为0,如果为0那么恰好需要一号顶点向 3 , 4 , 5... , m 3,4,5...,m 3,4,5...,m相连,否则我们对余数 r e s res res二进制拆分,实际上就是看某一位是否为 1 1 1,然后从第 m − 1 m-1 m1个节点开始作为最低位,如果该数二进制位为 1 1 1依次加边,最后输出即可

注意最大可能找到 1 < < 64 1<<64 1<<64恰好爆 u n s i g n e d    l o n g    l o n g unsigned ~~long ~~long unsigned  long  long,那么使用 _ _ i n t 128 \_\_int128 __int128

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e5+10;

vector<pii> ans;

void write(__int128 x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ull k,n;
    cin>>k>>n;
    if(k==1){
        cout<<"2 1\n1 2\n";
        return 0;
    }
    if(k==2){
        cout<<"3 3\n1 2\n2 3\n1 3\n";
        return 0;
    }
    __int128 one=1;
    ull x=0,m;
    while((one<<x)<k) x++;
    //cout<<"x:"; write(x); cout<<endl;
    
    m=x+2;
    ans.push_back({1,2});
    ans.push_back({m-1,m});
    for(int i=2;i<=m-2;i++){
        for(int j=i+1;j<=m;j++)
            ans.push_back({i,j});
    }
    
    ull res,p;
    if((one<<x)==k) res=0;
    else res=(ull)((__int128)k-(one<<(x-1)));
    //cout<<"res:"<<res<<endl;
    
    vector<int> tmp;
    p=res;
    while(res){
        if(res&1) tmp.push_back(1);
        else tmp.push_back(0);
        res>>=1;
    }
    
    //cout<<"binary:"; for(auto i: tmp) cout<<i; cout<<endl;
    if(p){
        for(int i=0,j=m-1;i<tmp.size();i++,j--) if(tmp[i]){
            ans.push_back({1,j});
        }  
    }else{
        for(int i=3;i<=m;i++) ans.push_back({1,i});
    }
   
    cout<<m<<" "<<ans.size()<<"\n";
    for(int i=0;i<ans.size();i++) cout<<ans[i].first<<" "<<ans[i].second<<"\n";
    return 0;
}

相关文章:

  • 技术人生
  • 2020智算之道复赛 D - 分数(素筛)
  • 无stencil buffer,绘制半透明planar shadow的一种方法
  • 2020牛客暑期多校第十场 A - Permutation(思维)
  • 2020牛客暑期多校第十场 E - Game(思维)
  • 《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之30---基于BREW的PTT服务...
  • HDU - 6805 Deliver the Cake(拆点+最短路)
  • 《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之31---LBS基于BREW的位置服务...
  • STL之multiset
  • Java网络编程从入门到精通(16):客户端套接字(Socket)的超时
  • 2020牛客暑期多校第十场 C - Decrement on the Tree(树的思维好题)
  • 页面校验用通用js
  • SPOJ - FIBOSUM Fibonacci Sum(递推公式/矩阵快速幂)
  • 保证唯一性只能靠建唯一索引
  • HDU - 6860 Fluctuation Limit(双向贪心/思维)
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • idea + plantuml 画流程图
  • k8s 面向应用开发者的基础命令
  • Mocha测试初探
  • mysql_config not found
  • nfs客户端进程变D,延伸linux的lock
  • 笨办法学C 练习34:动态数组
  • 编写高质量JavaScript代码之并发
  • 程序员该如何有效的找工作?
  • 关于字符编码你应该知道的事情
  • 诡异!React stopPropagation失灵
  • 计算机在识别图像时“看到”了什么?
  • 简单易用的leetcode开发测试工具(npm)
  • 前嗅ForeSpider教程:创建模板
  • 如何选择开源的机器学习框架?
  • 如何在 Tornado 中实现 Middleware
  • 原生JS动态加载JS、CSS文件及代码脚本
  • ​低代码平台的核心价值与优势
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #pragma multi_compile #pragma shader_feature
  • (1)虚拟机的安装与使用,linux系统安装
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (C)一些题4
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (区间dp) (经典例题) 石子合并
  • (算法)求1到1亿间的质数或素数
  • (未解决)macOS matplotlib 中文是方框
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)visual stdio 书签功能介绍
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理(六):替换字符串中匹配的子串
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .Net程序帮助文档制作
  • /var/lib/dpkg/lock 锁定问题