题解:P14145 荒谬
构造一个 DAG,距离不等于
有一个非常显然的做法,分出一个点作为中转,其余点的一半连到中转点,中转点连到剩下的点。这样就有
::anti-ai[赛时想到这就倒闭走人了。]
考虑哪些点距离不为
与中转点直接相邻的点个数是
因为有对称性,并且下面不能连到上面,所以直接考虑一部分。
这样就变成了:有一些点,连一些边,最大化距离为
这不就是原本的题吗?递归下去即可。
那么这样最终的点对数量是多少?
我们发现直接证明不是很好算,所以可以考虑有多少个点对距离不是
:::info[代码&提交记录]
#include <cstdio>
using namespace std;
void doit(int l, int r)
{
if(r - l <= 0) return;
int mid = (l + r) / 2;
for(int i=l;i<=r;i++)
{
if(i < mid) printf("%d %d\n", i, mid);
if(i > mid) printf("%d %d\n", mid, i);
}
doit(l, mid - 1);
doit(mid + 1, r);
}
int sum[2005];
int main()
{
int n;
scanf("%d", &n);
// 不想在递归的时候统计边数,先递推
for(int i=1;i<=n;i++)
{
sum[i] = sum[(i-1)/2] + sum[i/2] + (i - 1);
}
printf("%d\n", sum[n]);
doit(1, n);
return 0;
}
rec。 :::