题目大意:给一个
k
≤
5
×
1
0
5
k\le 5\times10^5
k≤5×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());
}