【jzoj4935】【构造】

来源:互联网 发布:js设置input必填 编辑:程序博客网 时间:2024/06/15 01:01

题目大意

这里写图片描述

解题思路

我们进行二进制拆分,从低位开始,给当前位置建一个子节点,如果是1则当前点变为新建节点,否则不变,再建一个新节点,当前点不变。可以发现变节点的情况我们把方案数+1,不变的情况我们把方案数*2,这样2^30>1e9,我们可以解决所有问题。

code

#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LL long long#define min(a,b) ((a<b)?a:b)#define max(a,b) ((a>b)?a:b)#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const maxn=60;int k,n,now,u[maxn+10],v[maxn+10];int main(){    freopen("d.in","r",stdin);    freopen("d.out","w",stdout);    while(scanf("%d",&k)!=EOF){        int n=1;now=1;        while(k!=1){            if(k&1){                u[n]=now;v[n]=n+1;n++;                now=n;            }            u[n]=now;v[n]=n+1;n++;            k=k>>1;        }        printf("%d\n",n);        fo(i,1,n-1)printf("%d %d\n",u[i],v[i]);    }    return 0;}
0 0