CF2120C Divine Tree 题解
跟这题一个道理。
下文令
考虑根为
知道了上下界,大胆猜测
初始状态为菊花图,从大到小考虑除根和
由于我们从大到小考虑,所以
回到题目,先选定一个根节点使得
初始状态为菊花图,从大到小考虑除根和
#include <bits/stdc++.h>
#define lowbit(o) o & -o
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 1000005;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const LL INF = 2e18;
LL fa[N];
void work()
{
LL n, m;
cin>>n>>m;
LL rt = -1;
for (LL i=1;i<=n;i++)
{
LL l = i + n - 1, r = (1 + i) * i / 2 + (n - i) * i;
if (l <= m && m <= r)
{
rt = i;
break;
}
}
if (rt==-1){
cout<<"-1\n";
return;
}
for (int i=1;i<=n;i++)
fa[i] = rt;
LL s = (1 + rt) * rt / 2 + (n - rt) * rt;
for (LL i=n;i>1;i--)
{
if (s == m)
break;
LL v = min(rt, i);
if (s - (v - 1) <= m)
{
LL id = m - s + v;
// s - v + x = m
fa[i] = id;
s -= v - id;
break;
}
fa[i] = 1;
s -= v - 1;
}
cout << rt<<'\n';
for (int i=1;i<=n;i++)
if (i != rt)cout<<fa[i]<<' '<<i<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int _T = 1;
cin >> _T;
while (_T--)
work();
return 0;
}