1 条题解
-
0
自动搬运
来自洛谷,原作者为

Lsrh666
Ciallo~(∠・ω< )⌒★搬运于
2025-08-24 22:29:25,当前版本为作者最后更新于2024-11-11 11:28:12,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
构造一棵树使得:
- 要求1:树的大小 尽量小。
- 要求2:相邻点的编号不同。
- 要求3:树的最大编号不能小于 。
同时给定 ,要求 。
为了方便维护,不妨设最大值 为根。
发现此时, 必定有 的儿子。
证明是显然的,假如没有这些儿子中的任意一个 ,将 换成 ,可以使树的最大值变成 。
接下来考虑换值,考虑到要求2,将根的儿子 换成 ,同时将 换成 。
但是一个 是不够的,我们需要 个这样的儿子。
但是,这样需要的操作次数太多,导致挂到55pts。
需要优化!
考虑到 的时候,我们用 替换掉了 。
这样, 就又重复出现了。
考虑用 换掉 ,用 换掉
但是 可以用 换掉,这样就循环起来了。
这样能实现减少总节点数的功能。#include <bits/stdc++.h> #define int long long #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define epr(i,j) for(int i=head[j];i;i=nxt[i]) using namespace std; const int MAXN=1e6+10; int head[MAXN],to[MAXN<<1],nxt[MAXN<<1]; int cnt=0,tot=0; inline void add(int x,int y){ to[++cnt]=y,nxt[cnt]=head[x]; head[x]=cnt; } inline int sol(int p,int cur){ int res=++tot; if(p==1) return tot; if(res==1) add(res,sol(p-1,1)); per(i,p-1-(res==1),1) rep(j,1,p-i+1+cur) add(res,sol(i,0)); return res; } signed main(){ ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); int k,x; cin>>k>>x; sol(k,0); cout<<tot<<'\n'; rep(i,1,tot) epr(j,i) cout<<i<<' '<<to[j]<<'\n'; return 0; }
- 1
信息
- ID
- 6493
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者