1 条题解
-
1
一个纯粹的构造题。本来不想设 的限制的,因为对正解提示性太大,但是没有这限制指不定有什么更简单的做法(
毕竟题源是 MO 题,其中的官方解答给的是 的解答, 是我自己的做法。
先讲下部分分。
直接手玩,或者写个爆搜随便搞搞,打个表就完了。
而且样例给了 然后 只有 个点,这些数据是什么你应该已经知道了,那就面向数据编程吧!接下来,我们先判无解。显然可以算两次。
$$\sum_{i=1}^{\frac{n(n-1)}{2}}(a_{x_i}+a_{y_i}+2k_i)=\sum_{i=1}^{n(n-1)}i, $$$$(n-1)\sum_{j=1}^{n}a_j \equiv \dfrac{n(n-1)(n^2-n+1)}{2}\pmod{2}. $$显然当 时左边为偶数,右边为奇数,矛盾!
另外我们有其他情况均有解。我们通过构造说明。
首先做 且 为偶数的情况。设 。则显然取 ,然后对 取 次 ,第 次取 。显然这样满足题目要求。
且 为奇数的情况当时的官方解答很复杂,如果有人有兴趣可以在评论区说,我后续可能会放(gu)上(gu)来(gu)。如果有人有简单的解法完成这个部分分可以私信我,
那说明我如果不设 的限制这题就会被水过。下面直接讲 。发现我们每一对 出现的次数在 增大时都不减,尝试归纳构造。
我们自然地想到最简单的情况:取 。我们在此基础上尝试构造。
首先我们思考如何处理 或 即 的情况。显然此时我们要将 到 的正整数分成 组,使得每组两数之差恰好取遍 到 各一次。这就是P7510 铃解缀。
然后考虑 即 的情况。显然我们要将 到 的正整数分成 组,使得每组两数之差取 到 各两次, 一次。这个的构造是容易的,具体如下(以下 表示 ):
也可以见代码中相关部分理解。
这样做是满足 的限制的,只要稍作计算就能够证明。
总时间复杂度 。
Code:
#include<cstdio> #define rg register int n,m,o; int cnt[3007]; int res[3007][3007]; int main() { scanf(" %d %d %d",&n,&o,&o); if(n&3^3) { printf("%d\n",n); for(rg int i=0;i<n;++i)printf("%d ",i); puts(""),res[1][cnt[1]=1]=1; for(rg int k=2,t;k<n;++k) { t=k*(k-1); if(k&2) { ++k,m=(k+1)>>1; res[k][++cnt[k]]=t+m; for(rg int i=1;i<m;++i) { res[i<<1][++cnt[i<<1]]=t+m-i; res[i<<1][++cnt[i<<1]]=t+k+m-i; res[(i<<1)-1][++cnt[(i<<1)-1]]=t+(k<<1)+m-i; res[(i<<1)-1][++cnt[(i<<1)-1]]=t+(k<<1)+k+m-i-1; } } else { m=k>>2; if(k&1) { res[1][++cnt[1]]=t+1; res[k][++cnt[k]]=t+k; res[k-2][++cnt[k-2]]=t+m+2; res[k-1][++cnt[k-1]]=t+((m+1)<<1); res[k>>1][++cnt[k>>1]]=t+k+(k>>1); for(rg int i=1;i<m;++i) { res[i<<1][++cnt[i<<1]]=t+((m+1)<<1)-i; res[i<<1|1][++cnt[i<<1|1]]=t+k+(m<<1)-i; res[k-(i<<1|1)][++cnt[k-(i<<1|1)]]=t+k+i; res[k-((i+1)<<1)][++cnt[k-((i+1)<<1)]]=t+2+i; } } else { res[1][++cnt[1]]=t+1; res[k-1][++cnt[k-1]]=t+m+2; res[k>>1][++cnt[k>>1]]=t+k+1; res[k][++cnt[k]]=t+((m+1)<<1); for(rg int i=1;i<m;++i) { res[i<<1][++cnt[i<<1]]=t+((m+1)<<1)-i; res[k-(i<<1)][++cnt[k-(i<<1)]]=t+k+i+1; res[k-(i<<1|1)][++cnt[k-(i<<1|1)]]=t+2+i; res[i<<1|1][++cnt[i<<1|1]]=t+k+(m<<1|1)-i; } } } } for(rg int i=1;i<n;++i) { for(rg int j=1;j<=n-i;++j) { printf("%d %d %d\n",j,j+i,res[i][j]-j+1); } } } else puts("-1"); return 0; }
- 1
信息
- ID
- 147
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 37
- 已通过
- 12
- 上传者