コード:
#include <ビット/ STDC ++ H> の#defineがっ長い長 の#define MAXN 50207 の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN) の#define MOD 1000777 使用して名前空間std。 構造体ツリー { int型のTOT; int型のLSON [MAXN * 270]、rson [MAXN * 270]。 LL MUL [MAXN * 270]。 INTイン(int型のx、int型のL、R INT、INT P、LL V) { int型O = ++ TOT。 LSON [O] = LSON [X]、rson [O] =のrson [X]。 IF(X)MUL [O] = MUL [X] * V%のMOD。 他MUL [O] = V; IF(L == R)戻り0; INT半ば=(L + R)>> 1。 IF(p <= MID)LSON [O] =イン(LSON [x]は、L、中、P、V)。 } 他rson [O] =イン(rson [x]は、中間+ 1、R、P、V)。 Oを返します。 LLクエリ(int型のx、int型のL、int型のR、int型のL、int型R) { IF(L> = L && R <= R)MUL戻り[X]。 LL再= 1。 INT半ば=(L + R)>> 1。 IF(L <= MID)再=再*クエリ(LSON [x]は、L、中、L、R)%MOD。 再(R> MID)場合= *クエリ(rson [x]は、中間+ 1、R、L、R)%MOD再。 再を返します。 } } TR。 INT CNT、N、M。 INT [1000004]、VIS [1000004]、あらかじめ[1000006]プライム、[MAXN] RT、[MAXN] cur変換。 MUL [MAXN]、[MAXN] ARR LL。 LLのqpow(LLベース、LLのK) { LL再= 1。 一方、(K) { (K&1)が再場合= *基地%のMOD再。 基地=ベース*基地%のMOD。 K >> = 1。 } 再を返します。 } 初期化(int型N)を無効 { (;私は= N <; I = 2 int型++ i)について { 場合(VIS [i]が!)プライム[++ CNT] = I; (INT J = 1; J <= CNT && 1LL *プライム[J] * iが<= N; J ++)用 { VIS = 1 [iがj]は[プライム*]。 もし(I%、プライム[J] == 0)ブレーク。 } } (; iが<= N I ++ I = 1 INT)用 { int型のx = ARR [i]は、CC = 0。 RT [I] =のRT [I-1]; もし(x == 1) { RT [I] = tr.ins(RT [I-1]、1、N、I、1)。 持続する; } CUR [++ CC]は[I] =室温。 (INT J = 1; J <= CNT && 1LL *プライム[J] *プライム[J] <= xと; ++ j)のための { IF(X%プライム[J] == 0) { (予備[プライム[J])であれば { CUR [CC + 1] tr.ins(CUR [CC] = 1、nは、[プライム[j]を】予め、1LL *プライム[J] * qpow((プライム[J] -1)、MOD-2)%のMOD)。 ++ CC; } CUR [CC + 1] = tr.ins(CUR [CC]、1、nは、[プライム[J] = I、1LL×(プライム[J] -1)* qpow(プライム[j]を事前に、MOD -2)%のMOD)。 ++ CC; 一方、(X%プライム[J] == 0)は、x / =プライム[J]。 } } (X> 1)であれば { (PRE [X])場合 { [X]、1LLの*第X *のqpow((X CUR [CC + 1] tr.ins(CUR [CC] = 1、nは、あらかじめ-1)、MOD-2)%のMOD)。 ++ CC; } [CC + 1] tr.ins = cur変換(CUR [CC]、1、nは、[X] = I、1LL×(X-1)予備* qpow(X、MOD-2)%のMOD)。 ++ CC; } RT [I] = CUR [CC]。 CUR [I] = 0;(; iが= CCを<++ iが1 = INT)のために } } int型のmain() { // setIO( "入力")。 scanf関数( "%d個の%のD"、&N、&M)。 int型のmx = 0; MUL [0] = 1。 (; iが<= N I ++ I = 1 INT)のために { scanf関数( "%のLLD"、およびARRは、[I])。 MUL [I] = MUL [I-1] * [I]%MOD ARR。 MX = MAX(MX、(INT)ARR [I])。 } 初期化(MX)。 LL lastans = 0。 以下のために(INT I = 1; I <= M; ++ I) { // lastans = 0。 int型のL、R。 scanf関数( "%dの%のD"、&L&R)。 L ^ = lastans、R ^ = lastans。 LLのREV = qpow(MUL [L-1]、MOD-2)。 lastans = MUL [R] *のREV%MOD * tr.query(RT [R]、1、N、L、R)%MOD。 printf( "%LLDする\ n"、lastans)。 } 0を返します。 }