ARC102 D - All Your Paths are Different Lengths

题解:

容易想到最后答案都是由若干个 2 2 的次幂加起来的,也就是第i个点向第 i+1 i + 1 个点连 2i1 2 i − 1 的边,但是这样只有 2x 2 x 条路径,剩下的 L2x L − 2 x 条怎么办呢?现在我们还剩下 L2x L − 2 x 条路径,注意到前 i i 个点可以凑出0~ 2i11 2 i − 1 − 1 ,所以我们这样做:每次先找到一个最大的 y y 使得2y<=L2x,那么找出那个可以凑出 2y 2 y 个数的前缀,向终点连一条对应权值的边。举个例子:( L=11 L = 11
如下连边,可以凑出 0 0 ~7
这里写图片描述
然后找到 y=1 y = 1 ,那么能凑出 21 2 1 个数的前缀是 1 1 2两个点,接下来的两个数是 8 8 9,所以这样连边:
这里写图片描述
最后是这样:
这里写图片描述

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=1000010;
const int inf=2147483647;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
int L,n=1,m=0,a[22],l=0;
struct Edge{int x,y,d;}e[70];
int main()
{
    L=read();
    int t=L-1;
    for(int i=0;(1<<i)<=t;i++)
    {
        n++;
        t-=(1<<i);
        e[++m].x=n-1,e[m].y=n,e[m].d=0;
        e[++m].x=n-1,e[m].y=n,e[m].d=(1<<i);
    }
    t=L;
    while(t)a[++l]=(t&1),t>>=1;
    int tot=(1<<(l-1));
    for(int i=l-1;i;i--)
    if(a[i])
    {
        e[++m].x=i,e[m].y=n,e[m].d=tot;
        tot+=(1<<(i-1));
    }
    printf("%d %d\n",n,m);
    for(int i=1;i<=m;i++)printf("%d %d %d\n",e[i].x,e[i].y,e[i].d);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值