제목 설명
그는 컬럼의 수를 알고있는 경우, 다음과 같은 세 가지 작업을 수행해야합니다
1. X 곱한 수의 각각의 섹션
2. X 다수의 각각의 섹션 플러스
3. 섹션의 수를 결정하고 각
입력 형식
첫 번째 라인은 각각 세 개의 정수 N, M, P를 함유하고, 총 수는 숫자, 동작의 열 수를 모듈로 (modulo).
수가 초기 값의 전 항목의 i 번째 열을 나타내고, 상기 제 2 라인은 공백으로 구분 N 정수를 포함한다.
다음 M 라인은 다음과 같은 3 또는 4의 정수, 동작을 나타내는 포함
동작 1 : 형식 : 1 명 XYK 의미 : Y (X), 상기 각 구간의 수를 곱한 값 k는
동작 2 : 형식 : 2 XYK 의미 구간 [X, Y 각각의 수 k는 플러스
작업 3 : 형식 : 3 XY 의미 : 출력 간격 [x 및 y,] 얻어진 결과를 모듈로 P의 각각의 숫자
출력 형식
출력은 라인의 정수, 세 작업의 결과가 포함되어 있습니다.
샘플 입출력
입력 # 1
38 5 5 1 2 5 4 3 2 1 4 1 3 2 5 1 2 4 2 2 3 5 5 3 1 4
출력 # 1
17 2
#INCLUDE <. 비트 / stdc ++ H> 의 typedef 긴 긴 LL; 사용하는 네임 스페이스 표준을; CONST의 INT maxn 2E5 + = 9 ; 구조체 나무 { INT의 L, R; LL의 합은, MUL을 추가; } A [maxn << 2 ]; LL S [maxn] P; 보이드 업데이트 ( INT의 K) { A [K] .sum = (a [K << 1 ] .sum + A [K << 1 | 1 ] .sum) %의 P; } 공극 빌드 ( INT의 K, INT의 L, INT의 R) { A [K] 펜닐 = 1, A [K] = .R R; A [K] .add = 0 ; A [K] .mul = 1 ; 경우 (L == R) { A [K] .sum = S [1]; 반환 ; } INT 중간 = (L + R) >> 1 ; 빌드 (K << 1 , L, MID); 빌드 (K << 1 | 1 중간 + 1 , R); 업데이트 (K); } 공극 푸시 ( INT의 K) { 경우 (== .L A [K] 이 [K]를 .R) { A [K] .add = 0 ; A [K] .mul = 1 ; 반환 ; } INT 중간 = (a [K] 펜닐 + A [K] .R) >> 1 ; A [K << 1 ] .sum = (a [K << 1 ] .sum * A [K] .mul + A [K] * .add (MID-A [K] 펜닐 + 1 )) %의 P; A [K << 1 | 1 ] .sum = (a [K << 1 | 1 ] .sum * A [K] .mul + A [K] * .add (a [K] .R-MID)) %의 P; A [K << 1 ] .add = (a [K << 1 ] .add * A [K] .mul + A [K] .add) %의 P; A [K<< X)1 | 1 ] .add = (a [K << 1 | 1 ] .add * A [K] .mul + A [K] .add) %의 P; A [K << 1 ] .mul = (a [K << 1 ] .mul * A [K] .mul) %의 P; A [K << 1 | 1 ] .mul = (a [K << 1 | 1 ] .mul * A [K] .mul) %의 P; A [K] .add = 0 ; A [K] .mul = 1 ; 반환 ; } 공극 changeplus ( INT의 K, INT의 L, INT의 R, INT { //을 COUT << A [K] .sum << "??"<< ENDL; 경우 (a [K] 펜닐> R || A [K] .R <l) 창 ; 경우 (L <= A [K] 펜닐 && R> = A [K] .R) { A [K] .sum = (a [K] + .sum X * (a [K] .ra [K] + .L 1 )) %의 P; A [K] .add = (a [K] + .add X) %의 P; 반환 ; } 푸시 (K); INT 중간 = (a [K] 펜닐 + A [K] .R) >> 1 ; // 경우 (L <= MID) changeplus (K << 1 , L, R, X); // (R> MID) 경우 changeplus (K << 1 | 1 , ) 업데이트 (K } 공극 changemul ( INT의 K, INT의 L, INT의 R, INT의 X는) { // COUT << .sum << "!"<< ENDL [K]을; 경우 (a [K] 펜닐> R || A [K] .R <l) 창 ; 경우 (L <= A [K] 펜닐 && R> = A [K] .R) { A [K] .sum = (a [K] *의 .sum의 X) %의 P; A [K] .mul = (a [K] .mul * X) %의 P; A [K] .add = (a [K] * .add X) %의 P; 반환 ; } 푸시 (K); INT 중간 = (a [K] 펜닐 + A [K] .R) >> 1 ; // 경우 (L <= MID) changemul (K << 1 , L, R, X); // (R> MID) 경우 changemul (K << 1 | 1 ], L, R, X) 업데이트 (K); 반환 ; } LL 쿼리 ( INT의 K, INT의 L, INT의 R) { 경우 (R <A [K] 펜닐 || L>은 [K] .R) 복귀 0 ; 푸시 (K); 경우 (L <= A [K] 펜닐 && R> = A [K]를 .R) { 반환 A [K] .sum 단계; } INT 중간 = (a [K] 펜닐 + A [K] .R) >> 1 ; LL ANS = 0 ; // (L <= MID) 경우 ANS = (ANS 쿼리 + (K << 1 , L, R)) %의 P; // (R> MID) 경우 ANS = (ANS 쿼리 + (K << 1 | 1 %의, L, R)) ; P 반환 ANS를; } INT 의 main () { INT의 N, m, I; scanf와 ( " % D % % LLD D " , 및 N, M, P); 대 (I = 1 ; i가 <= N; ++ i가 ) 는 scanf ( " %의 LLD " , S [I]); 구축 ( 1 , 1 , N); 반면 M-- ( ) { INT, L, R을 선택; 게요 X; scanf와 ( " %의 D " , 및 선택 해제); 경우 (최적화 된 == 1 ) { 는 scanf ( " % D % % LLD D ' , L, R, X); changemul ( 1 , L, R, X); } 경우 (최적화 된 == 2 ) { 는 scanf ( " % D % % LLD D ' , L, R, X); changeplus ( 1 , L, R, X); } 경우 (최적화 된 == 3) { 는 scanf ( " % d 개 %의 D ' , L, R); 의 printf ( " % LLD \ 없음 " 쿼리 ( 1 , L, R)); } } }