[ural 2124]. Algebra on Segment

题意

给出一个模\(p\)\(p\)是素数)意义下的序列,支持两种操作:

  1. 区间乘一个数;
  2. 询问一个区间的元素构成的群的大小。

保证序列中的数时时刻刻不为\(0\)

题解

一道好题……sb了好久。
第一个想法显然是先找到一个原根\(g\),再取指标进行运算。
然后对于一个区间\(g ^ {k_l}, g ^ {k_{l + 1}}, \ldots, g ^ {k_r}\),生成群的生成元\(\omega\)\(g ^ {(\gcd{k_l, k_{l + 1}, \ldots, k_r, p - 1})}\),则群的大小为\(\frac{p - 1}{ind_g(\omega)}\)
看这个\(\gcd\),因为要区间修改,所以要维护原序列和原序列的差分两个数组,因为
\[ \gcd(x_1, x_2, \ldots, x_n) = \gcd(x_1, x_2 - x_1, \ldots, x_n - x_{n - 1}) \]
这样便把区间修改变成单点修改。
复杂度是\(\mathcal O((n + q) \sqrt {(n + q) p} + q \log ^ 2 n)\),因为要bsgs求指标(我tmbsgs块大小还写挂了)。
然而这样是过不了的。那咋整啊?
XZA说指标的信息有冗余,实际上只需要求阶即可(求阶是\(\mathcal O(\log ^ 2 p)\)的)。然而当时并没有理解这句话的意思,尽管感性理解好像是这回事。
考虑直接用阶做。
假设我们已经知道了区间\([l, r]\)中每个元素的阶,那么如何求其生成群的大小?考虑两两合并。
对于一个阶为\(a\)的元素和一个阶为\(b\)的元素,其生成的群可分别表示为\(<g ^ {\frac{p - 1}{a}}>, <g ^ {\frac{p - 1}{b}}>\)
那么合并之后,群可表示为\(<g ^ {\gcd{(\frac{p - 1}{a}}, \frac{p - 1}{b})}>\)。则新的群的大小为\(\frac{p - 1}{\gcd{(\frac{p - 1}{a}}, \frac{p - 1}{b})}\)
简单运算一下,发现就等于\(\text{lcm} (a, b)\)
这其中用到了一个很基础的定理:循环群的大小等于其生成元的阶。

猜你喜欢

转载自www.cnblogs.com/psimonw/p/11790321.html