CF1375 题解

CF 1375

都是结论题。。都不擅长

A

奇数位置为正,偶数位置为负。

B

显然可以构造出最大的矩阵:(a_{i,j}) 等于和 ((i,j)) 相邻的格子的数量。判断是否合法即可。

C

结论是如果 (a_1 < a_n) 就是 YES,否则是 NO

首先证明 (a_1 < a_n) 一定可行:

  • 每次找到第一个比 (a_1) 大的位置 (p),然后可以删掉 ([2..p-1]),最后删掉 (p)
  • 因为 (a_1 < a_n) 所以 (a_n) 是最后一个被找到的,也是最后一个被删除的。

然后证明 (a_1 > a_n) 一定不行:

  • 如果某一次操作包含了 (a_1),那么操作后剩下的数不会比 (a_1) 小,并且这个数永远是在最开头的位置
  • 考虑找出从 (1) 开始的上升子序列,把序列分成了若干段。
  • 除了最后一段之外的都可以消掉,最后一段发现无论如何也消不掉(因为这一段里最大的都比前面那个分界点要小)

D

我们考虑直接复原成 (0 ldots n-1)

假设现在序列还没有被复原,我们分类讨论:

  • (mex < n),直接令 (a[mex] = mex),没有被安排好的空 (-1)
  • (mex = n),找到一个位置满足 (a[i] eq i),填上这个值。下一次一定会跳到第一种情况并且填上这个位置的值,两次操作让没有被安排好的空 (-1)

所以操作次数 $ leq 2n$。

E

先考虑互不相等怎么做:

先贪心想想能不能把所有的逆序对都选上:

考虑从小往大挨个枚举每个数,只考虑这个数字后面的逆序对,那么枚举到数字 (x) 的时候 (<x) 的数字的相对位置已经确定了,假设 (x) 后面 (<x) 的数字下标分别是 (i_1,i_2,ldots,i_m),设当前 (x) 的位置为 (ps),执行操作 ((ps,i_m),(ps,i_{m-1}),ldots,(ps,i_1)) 即可。发现 (x) 到了所有比它小的数字的后面,相对顺序也确定了。

F

首先想一想先手必胜的情况是啥样的:肯定是你的 (a) 从大到小排序后,有 (a_1-a_{2} = a_{2}-a_{3}) 并且上一次选择的是 (a_1)。然后你给出一次操作 (a_2-a_1) 即可。

先手三步必胜。

第一步:给一个非常大的数字,相当于 ban 掉了最大值。

第二步:设从大到小排序后的序列为 (a),设 (d_1 = a_1-a_2,d_2 = a_2-a_3)。我们给出 (2d_1+d_2)

第三步:首先上一步后手不能选择加到 (a_1) 上(违反规则),分类讨论一下:

  • 加到 (a_2) 上:序列变成了 (a_1,2a_1-a_3,a_3) 公差是 (a_1-a_3) 并且中间的最大值被 ban 了,只需要给出 (a_1-a_3) 就赢了。
  • 加到 (a_3) 上:序列变成了 (a_1,a_2,2a_1-a_2) ,公差是 (a_1-a_2),并且第三个是最大值且被 ban 了,只需要给出 (a_1-a_2) 就赢了。

G

结论:答案是黑白染色后颜色数取 min 后减一。

首先我们将树黑白染色。发现菊花图一定是一个黑点 (n-1) 个白点(或倒过来)。我们这样的操作,选择 ((a,b,c)) 每次只改变一个点的染色(也就是 (a) 的颜色)。所以正确性就显而易见了。

谁能想到黑白染色啊。。。

H

考虑对值域分块。

对值域分块一个很重要的性质是原序列的一个连续区间可以被分成这 (B) 个值域的一些连续区间的并。

于是我们要对于每一块值域内的每一对区间都预处理出这样的集合。询问的时候可以 (O(frac{n}{B})) 得到一组答案,总代价就是 (O(qfrac{n}{B}))

考虑处理每一对区间的时候对值域分治,首先递归做完两个子问题值域后就可以枚举每一个当前值域里存在的区间合并了,当前值域里的每一个区间一定由至多两个子问题中的区间构成,所以复杂度是 (T(n) = 2T(frac{n}{2})+O(n^2)Rightarrow T(n) = O(n^2))

所以总使用次数是 (O(frac{n}{B}B^2+qfrac{n}{B}) = O(n(B+frac{q}{B}))),当 (B=sqrt{B}) 的时候达到理论复杂度 (O(2nsqrt{q}) o 2097152)。恰好可以通过本题。

I

首先先做一下链接 里面的 K 题:

题意大概是一开始给定二维平面上一些点,要求你加入最少数量的点满足形成了一个网格形。(K imes K) 网格的定义是存在一组常数 (a,b,c,d) 满足所有的点都可以用 ((a+ci+dj,b+di-cj),i,j in [0,K-1]) 表示出来。

我们对任意两对点做差,可以得到形式形如 ([c(i-i')+d(j-j'),d(i-i')-c(j-j')]) 的向量。发现这些向量都可以由两组基 ([c,d],[d,-c]) 整数系数线性表出。并且两组基满足模长相等,互相正交。

所以现在我们差分出 (n-1) 个向量,相当于要找一组尽量大的基,满足这一组基能整数系数线性表出所有的向量。

我们考虑挨个合并:假设现在有两组向量 ((a,b))((c,d)) 我们类似欧几里得算法做一个辗转相除的东西:每次设模长较小的向量为 ((a,b)),先将 ((c,d)) 投影到 ((a,b)) 上,然后算出来能尽量减多少次 ((a,b)) 能让它的投影尽量接近原点。对 ((a,b)) 的法向量也算一次。直到某一个消成 (0) 为止。最后得到的向量就可以直接带进去算出每个点的坐标了。

这个题也是类似的思考思路:首先我们考虑三维空间中的旋转我们要用四元数而不是用复数了。首先可以速成一下四元数(如果想去理解本身的意义可以去看 3b1b 之类的东西):

四元数定义为 (q = a+bi+cj+dk),其中满足:

[egin{aligned} ij=k\ jk=i\ ki=j\ ji=-k\ kj=-i\ ik=-j\ i^2 = j^2 = k^2 = -1 end{aligned} ]

乘法满足分配率,但是不满足交换律。

四元数的模定义为 (|q| = sqrt{a^2+b^2+c^2+d^2}),接下来记 (||q|| = a^2+b^2+c^2+d^2)

四元数的共轭定义为 (overline q = a-b_i-c_j-d_k)

因为有 (qoverline q = ||q||),所以可以得到 (q) 的乘法逆元为 (frac{overline q}{||q||})

四元数可以看成是一个实数和三维向量的更一般的组合形式,可以记做 (q=(a,(b,c,d)))

旋转:刚体坐标系中的 (P) 点绕单位向量 ((x,y,z)) 的轴旋转 ( heta),可以令 (q = (cos frac{ heta}{2},(x,y,z)sin frac{ heta}{2}))

(p = (0,P)),那么旋转后的点 (P' = qpq^{-1} = frac{qpoverline q}{qoverline q})

接下来我们来考虑这个题怎么做:

首先我们发现满足题目性质的 (vec r_1,vec r_2,vec r_3) 长度一定都是整数。首先我们可以把 (vec r_3) 写成以下形式:

[vec r_3 = pm frac{vec r_1 imes vec r_2}{|vec r_1|} ]

可以发现 (vec r_1 imes vec r_2,vec r_3) 每一维都是整数,所以 (|vec r_1|) 是有理数。

考虑 (|vec r_1|^2) 是整数,显然非整数的平方显然不会是整数,所以可以得到 (|vec r_1|) 是整数。

我们不妨把问题转换成找到一个变换 (q)(这里 (q) 是一个四元数)满足存在一组在 ((vec e_x,vec e_y,vec e_z)) 下的一组向量 (vec b_i) 经过如下变换:

[vec{v} mapsto k cdot frac{q cdot vec{v} cdot ar{q}}{q cdot ar{q}} ]

变换到基 ((vec r_1,vec r_2,vec r_3)) 下向量是 (a_i),即输入的向量,显然这里 (b_i) 也都是整数

根据四元数的定义可以得到,我们可以把以上变换写成矩阵的形式:

[frac{k}{s^{2}+x^{2}+y^{2}+z^{2}} cdotleft(egin{array}{ccc}s^{2}+x^{2}-y^{2}-z^{2} & 2 x y-2 s z & 2 x z+2 s y \ 2 x y+2 s z & s^{2}-x^{2}+y^{2}-z^{2} & 2 y z-2 s x \ 2 x z-2 s y & 2 y z+2 s x & s^{2}-x^{2}-y^{2}+z^{2}end{array} ight) ]

考虑 ((vec e_x,vec e_y,vec e_z)) 坐标都是整数,((vec r_1,vec r_2,vec r_3)) 也是,也就意味着矩阵里的每一个元素都是整数。

我们设 (frac{P}{Q} = frac{k}{s^2+x^2+y^2+z^2}),那么肯定要求 (Q) 能整除 (s^2+x^2+y^2+z^2) 和矩阵中所有元素,发现矩阵中所有形如二项的东西都可以被辗转相减消掉,所以 (Q) 要整除:

[egin{aligned} operatorname{gcd}left(egin{array}{c}s^{2}+x^{2}+y^{2}+z^{2} \ s^{2}+x^{2}-y^{2}-z^{2} \ s^{2}-x^{2}+y^{2}-z^{2} \ s^{2}-x^{2}-y^{2}+z^{2}end{array} ight)=operatorname{gcd}left(egin{array}{c}s^{2}+x^{2}+y^{2}+z^{2} \ 2left(y^{2}+z^{2} ight) \ 2left(x^{2}+z^{2} ight) \ 2left(x^{2}+y^{2} ight)end{array} ight)=operatorname{gcd}left(egin{array}{c}s^{2}+x^{2}+y^{2}+z^{2} \ 2left(y^{2}+z^{2} ight) \ 2left(x^{2}+z^{2} ight) \ 4 z^{2}end{array} ight) end{aligned} ]

我们可以发现 (gcd(a,b) | gcd(ka,b)),所以 (Q) 还整除:

[egin{aligned} operatorname{gcd}left(egin{array}{c}4left(s^{2}+x^{2}+y^{2}+z^{2} ight) \ 4left(y^{2}+z^{2} ight) \ 4left(x^{2}+z^{2} ight) \ 4 z^{2}end{array} ight)=4 operatorname{gcd}left(s^{2}, x^{2}, y^{2}, z^{2} ight)=4 end{aligned} ]

也就是我们的变换可以写成如下形式:

[vec{v} mapsto frac{k}{4} cdot q cdot vec{v} cdot ar{q} ]

其中 (k) 是一个整数系数。

题解说如果我们用的四元数满足 (a,b,c,d in mathbb{Z}),那么叫做 Lipschitz quaternions 它不能组成一个 Euclidean domain 所以没有辗转相减,所以我们要考虑扩到 Hurwitz quaternions 下,它是一个 Euclidean domain ,也就是所有形如 (a,b,c,d in {x|xin{mathbb Z}} cap {x|xinmathbb{Z}+0.5}) 的四元数。(这里我是真的学不下去了,没有抽象代数基础,就先记住吧反正是来学习四元数的)

那么变换可以写成如下形式:

[vec{v} mapsto frac{k}{2} cdot q cdot vec{v} cdot ar{q} ]

我们在代码里辗转相除的时候要除多少这个四元数也是要保证只能是 Hurwitz quaternion 才能保证正确性。

如果我们能求出这个 (q),只需要把 ((vec e_x,vec e_y,vec e_z)) 对着变换过去就得到了答案。

为了接下来讨论方便,我们先把 (vec v_i) 都乘二,也就是我们现在的变换是 (vec{v} mapsto k cdot q cdot vec{v} cdot ar{q})

我们设 (g = gcd(a_1,ldots,a_n)) ,这里的 gcd 是定义在Hurwitz quaternions 上的。

(G =gcd(||a_1||,ldots,||a_n||)),可以发现合法的 (q) 一定要满足 (k^2||q||^2) 整除 (G)

证明:

首先 (a_i = kqb_ioverline q),因为有 (||x|| imes ||y|| = ||x imes y||)那么说明 (||a_i|| = ||k|| imes||b_i|| imes ||overline q ||),又因为 (||q|| = ||overline q||),那么就有 (||a_i|| = k^2 ||q||^2 imes b_i^2),那么一定有 (k^2 ||q||^2) 整除 (G)

所以我们可以直接搜出所有满足条件的 (||q||),发现只有 (500) 个。

接下来考虑我们如何构造一个 (q)

首先有一个结论:如果 (g) 已经是最简形式了(也就是 (gcd(a,b,c,d) = 1)),那么如果 (||g|| = ab),就意味着存在唯一的 (q,p) 满足 (g=qp)(||q||=a,||p||=b)

那么我们可以发现我们要求的 (q=gcd(g,||q||))

证明:

[egin{aligned} k_1q = g (1)\ k_2q = ||q||\ (1) Rightarrow ||k_1|| dot ||q|| = ||g||\ end{aligned} ]

所以一定存在 (g = q imes ??),并且取 gcd 就是取了尽量大的 (q)

然后检验的话就是:

[egin{aligned} a_i &= qb_ioverline qRightarrow\ b_i &= q^{-1}a_ioverline q^{-1}\ &= frac{overline q}{||q||}a_ifrac{q}{||q||} end{aligned} ]

(比例系数 (k) 已经算在里面了)

只需要判断 (b_i) 是否每一维都是整数即可。

最后输出直接把 ((vec e_x,vec e_y,vec e_z)) 变换过去即可。

我也不是很懂这一块东西,如果哪里理解除了偏差请在评论区指出谢谢!

原文地址:https://www.cnblogs.com/rainair/p/14308677.html