【题解】Patisserie ABC 2 \ Minflip Summation

\(\texttt{ABC200 }\text{Patisserie ABC 2}\)

给定正整数 \(N,K\) 。生成 \(n^3\) 个三元组 \((i,j,k),1\le i,j,k\le N\) ,将它们升序排序,第一、第二、第三关键字分别是: \(i+j+k\)\(i\)\(j\) 。问第 \(K\) 小的三元组是什么。( \(1\le N\le 1e6,1\le K\le N^3\)

\(\text{cnt}_{sum}\) 代表满足 \(i+j+k=sum\) 的三元组 \((i,j,k),1\le i,j,k\le N\) 的数量,再设 \(\text{CNT}_i=\sum_{j=3}^i \text{cnt}_j\) 。则:

\[\text{cnt}_{l}=[x^{l-3}]\frac{(1-x^N)^3}{(1-x)^3} \]

再和 \(f(x)=1+x+x^2+\cdots\) 卷一次,简单地二项式展开和翻转上下指标,就得到了:

\[\begin{aligned} \text{CNT}_l&=[x^{l-3}]\frac{(1-x^N)^3}{(1-x)^4} \\ &=[x^{l-3}]\sum_{i=0}^{\infty}\binom{i+3}{3}x^i(1-3x^N+3x^{2N}-x^{3N}) \\ &=\binom{l}{3}+[l\ge N](-3)\binom{l-N}{3}+[l\ge 2N]3\binom{l-2N}{3}+[l\ge 3N](-1)\binom{l-3N}{3} \end{aligned} \]

由于 \(\text{cnt}\) 恒为正,故 \(\text{CNT}\) 单调增,可以二分确认第 \(K\) 位的 \(i+j+k\) 是多少。

固定了 \(i+j+k\) 的值后,再类似地推导满足 \(j+k=sum\) 的二元组 \((j,k),1\le j,k\le N\) 的数量 \(\text{cnt}'_{sum}\) 的后缀和,通过二分确定 \(i\) ,就可以 \(O(1)\) 确定第 \(K\) 小的三元组。具体地:

\[\text{cnt}'_{l}=[x^{l-2}]\frac{(1-x^N)^2}{(1-x)^2} \]

后缀和前缀之间互相转化是 \(O(1)\) 的,所以这里类似地推导前缀:

\[\begin{aligned} \text{CNT}'_l&=[x^{l-2}]\frac{(1-x^N)^2}{(1-x)^3} \\ &=\binom{l}{2}+[l\ge N](-2)\binom{l-N}{2}+[l\ge 2N]\binom{l-2N}{2} \end{aligned} \]

总复杂度 \(O(\log(n))\)

组合意义比较强的、多种关键字排序的问题,先考虑一种关键字,通过对一个关键字内的数量求前缀和,二分确定在哪个关键字内,重复做即可。

官方社论里给出的是 \(O(n)\) 的做法,然而如果要加强数据就得上高精了 这个 \(O(\log(n))\) 的做法运算过程中本来就会爆 long long ,如计算组合数的部分。但考察到总共三元组的数量不会爆 long long ,所以求前缀和时必然不会爆 long long ,合理使用 unsigned long long 自动溢出是可行的。

例如,您可以使用如下的代码求解 \(\binom{x}{3}\)

inline unsigned long long bin3(int x)
{
	if(x%6==0) return 1ull*(x/6)*(x-1)*(x-2);
	if(x%6==1) return 1ull*(x)*((x-1)/6)*(x-2);
	if(x%6==2) return 1ull*(x)*(x-1)*((x-2)/6);
	if(x%6==3) return 1ull*(x/3)*((x-1)/2)*(x-2);
	if(x%6==4) return 1ull*(x/2)*((x-1)/3)*(x-2);
	if(x%6==5) return 1ull*(x)*((x-1)/2)*((x-2)/3);
}

所以放在 \(\text{ABC}\) 里这个数据范围其实比较合适。

\(\square\)

\(\texttt{ABC200 }\text{Minflip Summation}\)

给定由 10? 构成的字符串 \(S'\)​ 和正整数 \(k\)​ ,从而得到 \(k\)​ 个 \(S'\)​ 顺序拼接而成的字符串 \(S\)​ 。? 可以任意地填写 10 ,设 \(S'\)​ 中的 ? 数量为 \(q\)​ ,这样得到了 \(2^{qk}\)​ 个新字符串。考虑用最少的步数将每一个新字符串变换成全由 1 构成的字符串或者由 0 构成的字符串,变换规则为区间取反。输出这些最少步数的总和。答案模 \(10^9+7\)​ 。( \(1\le|S'|\le 1e5,1\le k\le 1e9\)​ )

第一个小 trick 是考虑异或差分,按位异或的逆运算也是按位异或。这样,区间修改就转化为单点修改。目标是使差分数组均变为 0 ,单点修改可以一次只取反一个,也可以一次取反两个,所以只需要考察有几个 01 段和 10 段。设有 \(k\) 个这样的段,则至少需要修改 \(\lfloor\frac{k+1}{2}\rfloor\) 次修改,且可以做到。具体地,两两配对修改后,若还有剩余一个点,再修一次。据此,先考虑不存在 ? 的情况 ,从左往右扫来转移,修改次数增加当且仅当段数从偶数变化到奇数,可以得到:

  • 若当前位为 0 ,那么修改次数增加的充要条件是第一位为 1 且前一位为 1
  • 若当前位为 1 ,那么修改次数增加的充要条件是第一位为 0 且前一位为 0

所以,次数的增加与否,仅和第一位和前一位有关。

在加入 ? 后,只需要把 \(\text{mark}_i(\text{第一位},\text{前一位})\) 的推广到 \(\text{cnt}_i(\text{第一位},\text{前一位})\) ,也就是说,某种状态可能不只出现一次,但步数的增加方式是类似的。

设计状态:

\[\begin{pmatrix} \text{cnt}_i(0,0) \\ \text{cnt}_i(0,1) \\ \text{cnt}_i(1,0) \\ \text{cnt}_i(1,1) \\ \sum_{j=1}^i\text{step}_j \end{pmatrix} \]

简记为 \(\text{A}_i\) 。考虑从第 \(i-1\) 到第 \(i\) 位的转移矩阵 \(M_i\)

  • 若第 \(i\) 位是 0 ,则转移矩阵 \(\text{Zero}\)

\[\begin{pmatrix} 1 &1 &0 &0 &0\\ 0 &0 &0 &0 &0\\ 0 &0 &1 &1 &0\\ 0 &0 &0 &0 &0\\ 0 &0 &0 &1 &1 \end{pmatrix} \]

  • 若第 \(i\) 位是 1 ,则转移矩阵 \(\text{One}\)

\[\begin{pmatrix} 0 &0 &0 &0 &0\\ 1 &1 &0 &0 &0\\ 0 &0 &0 &0 &0\\ 0 &0 &1 &1 &0\\ 1 &0 &0 &0 &1 \end{pmatrix} \]

  • 若第 \(i\) 位是 ? ,则转移矩阵 \(\text{Que}=\text{Zero}+\text{One}\)

\(k\)\(S'\) 拼接,只需求出 \(\prod_{i=1}^{|S'|}M_i\) 后套个快速幂即可。

总复杂度 \(O(|S'|+\log(k))\)

\(\square\)

posted @ 2021-06-28 14:04  gsj_z  阅读(146)  评论(0)    收藏  举报