直径 - 构造

题目大意:给一个 k ≤ 5 × 1 0 5 k\le 5\times10^5 k5×105,求一个点数不超过 5000 5000 5000的树使得其直径数量是k。
题解:通过本地打表发现可以构造一个不超过三叉的扫把,点数分别是a,b,c,那么答案就是ab+bc+ac,对于这个范围的点数能够对每个k构造出来。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define showe(u,v,w) printf("%d %d %d\n",u,v,w)
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
namespace subtask5{
    inline int acceptable_solution(int k)
    {
        int n=5000;
        rep(a,1,n-3) if(k%a==0)
        {
            int b=k/a;if(a+b+2>n) continue;
            int x=a+b+1,y=x+1,w=10;
            printf("%d\n",a+b+2);
            rep(i,1,a) showe(i,x,w);
            rep(i,1,b) showe(i+a,y,w);
            showe(x,y,1);return 0;
        }
        rep(a,1,n-4) rep(b,1,n-4-a)
        {
            if(a*b>=k) break;
            if((k-a*b)%(a+b)>0) continue;
            int c=(k-a*b)/(a+b);
            if(a+b+c+4>n) continue;
            printf("%d\n",a+b+c+4);
            int x=a+b+c+1,y=x+1,z=y+1,t=z+1,w=10;
            rep(i,1,a) showe(i,x,w);
            rep(i,a+1,a+b) showe(i,y,w);
            rep(i,a+b+1,a+b+c) showe(i,z,w);
            showe(x,t,1),showe(y,t,1),showe(z,t,1);
            return 0;
        }
        assert(0);
        return 0;
    }
}
int main()
{
    return subtask5::acceptable_solution(inn());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值