Whether it is good to take the model or not, it frees the majority of oier from the abyss of high precision.
However, the modulo operation is not always so convenient.
For example, division is inevitable in our operations.
Most of the time, the question will tell us that the number of Modulo operations is a prime number, or at least the divisor and the number of Modulo operations are mutually qualitative, so that we can use the Euler's Theorem to solve this problem.
However, unfortunately, it still happened.
The number of modulus required for this question is arbitrary ~~
The question itself is not difficult. We can use the back-to-back bitwise statistics + tree-like array, but Division is inevitable in the reordered formula. What should we do?
From the bidding process of this question, SHIELD found the following method that is not very elegant:
First, we will take the number of modulus to decompose the prime factor, and then each time we want to multiply or divide a number, we will put forward the same quality factor of that number as the number of modulus, this factor is "violent" (that is, there is a division to directly divide the score, and then calculate the value quickly when it is used), and the other part is mutually dependent on the number of modulus, you can directly obtain its multiplication inverse element.
Since the number of prime factors of a number is log-level, a large amount of preprocessing can be used to evenly share the O (logn) of the modulo process)
However, the algorithm constant is still very large. What should I do?
I thought about a more effective constant optimization, that is, the multiplication inverse element of a number can be "Memorized", and the addition of this optimization program can be nearly doubled.
I feel that the algorithm is not very beautiful, so I want to implement it more beautifully ~~
Code:
Program syj; <br/> const <br/> maxn = 300005; <br/> type <br/> arr = array [0 .. 43] of longint; <br/> var <br/> N, Max, I, J, K, PHM, Mo, DT: longint; s, Ans: int64; <br/> A, B, C, sh, NE, u: array [0 .. maxn] of longint; <br/> pH: array [0 .. maxn] of longint; <br/> D: array [0 .. 43] of longint; <br/> Z: array [0 .. 43, 0 .. maxn] of longint; <br/> F, G: arr; <br/> procedure Update (I: longint ); <br/> begin <br/> while I <= max do begin <br/> Inc (B [I]); Inc (I, I and-I ); <br/> end; <br/> procedure ask (I: longint; var S: longint); <br/> begin <br/> S: = 0; <br/> while I> 0 do begin <br/> Inc (S, B [I]); Dec (I, I and-I ); <br/> end; <br/> function calc (I: longint): longint; <br/> procedure MUL (N: longint ); <br/> begin <br/> if n = 1 then pH [I]: = I else begin <br/> MUL (n> 1 ); <br/> pH [I]: = int64 (pH [I]) * pH [I] mod Mo; <br/> If Odd (n) then pH [I]: = int64 (pH [I]) * I mod Mo; <br/> end; <br/> begin <br/> If pH [I]> 0 Then exit (pH [I]); <br/> MUL (PHM); <br/> calc: = Ph [I]; <br/> end; <br/> function work (I, j: longint; var F: ARR): int64; <br/> var K: longint; <br/> begin <br/> If I = 0 Then exit (0); <br/> Work: = 1; <br/> while I> 1 do begin <br/> K: = sh [I]; <br/> if u [k]> 0 then Inc (F [U [K], j) else <br/> If j> 0 then work: = work * k mod Mo <br/> else work: = work * calc (k) mod Mo; <br/> I: = ne [I]; <br/> end; <br/> begin <br/> assign (input, 'per. in '); reset (input); <br/> assign (output,' per. out'); rewrite (output); <br/> readln (n, Mo); <br/> K: = Mo; PHM: = 1; <br/> for I: = 2 to trunc (SQRT (k) DO <br/> if K MoD I = 0 then begin <br/> Inc (DT ); d [DT]: = I; U [I]: = DT; J: = 1; <br/> while K MoD I = 0 do begin <br/> K: = K Div I; J: = J * I; <br/> end; <br/> PHM: = PHM * (J Div I * (I-1 )); <br/> end; <br/> if k> 1 then PHM: = PHM * (k-1); <br/> Dec (PHM, 1 ); <br/> If (k> 0) and (K <= N) then begin <br/> Inc (DT); D [DT]: = K; U [k]: = DT; <br/> end; <br/> for I: = 1 to DT do begin <br/> Z [I, 0]: = 1; <br/> for J: = 1 to n do Z [I, j]: = int64 (Z [I, J-1]) * d [I] mod Mo; <br/> end; <br/> for I: = 1 to n do begin <br/> Read (A [I]); <br/> If a [I]> MAX then Max: = A [I]; <br/> end; <br/> if n> MAX then Max: = N; <br/> for I: = 2 to Max do <br/> for J: = 1 to Max Div I do <br/> If sh [I * j] = 0 then begin <br/> Sh [I * j]: = I; ne [I * j]: = J; <br/> end; <br/> S: = 1; ans: = 1; <br/> for I: = n downto 1 do begin <br/> ask (A [I]-1, k); <br/> fillchar (G, sizeof (G), 0 ); <br/> J: = work (k, 1, g); <br/> Inc (C [A [I]); <br/> S: = S * Work (C [A [I],-1, F) mod Mo; <br/> J: = S * j mod Mo; <br/> If j> 0 then <br/> for K: = 1 to dt do <br/> J: = int64 (j) * Z [K, G [k] + F [k] mod Mo; <br/> Inc (ANS, J); <br/> Update (A [I]); <br/> S: = S * Work (n-I + 1, 1, F) mod Mo; <br/> end; <br/> writeln (ANS mod Mo ); <br/> close (input); close (output); <br/> end. <br/>
Faster than SHIELD, haha ~