Title Description
If that is known to a number of columns, you need to perform the following three operations:
1. The section of each of a number multiplied by x
2. The section of each of a number of x plus
3. determine a number of sections and each
Input Format
The first line contains three integers N, M, P, respectively, and the total number modulo the number of columns of numbers, operations.
The second line contains N integers separated by spaces, wherein the number indicates the i-th column of the item i of the initial value.
Next M lines contains an integer of 3 or 4, represents an operation, as follows:
Operation 1: Format: 1 XYK Meaning: the interval [x, y] k multiplied by a number in each
Operation 2: Format: 2 XYK Meaning: the interval [x, y] k each number plus
Operation 3: Format: 3 XY Meaning: output interval [x y,] and the number of each of the modulo P of the results obtained
Output Format
Output contains an integer number of lines, that is, the results of all three operations.
Sample input and output
5 5 38 1 5 4 2 3 2 1 4 1 3 2 5 1 2 4 2 2 3 5 5 3 1 4
17 2
Description / Tips
Constraints of time: 1000ms, 128M
Data Scale:
For 30% of the data: N <= 8, M <= 10
For 70% of the data: N <= 1000, M <= 10000
To 100% of the data: N <= 100000, M <= 100000
(Data has been strengthened ^ _ ^)
Sample Description:
Therefore, output should be 17,2 (40 mod 38 = 2)
/// /// _ooOoo_ /// o8888888o /// 88" . "88 /// (| -_- |) /// O\ = /O /// ____/`---'\____ /// .' \\| |// `. /// / \\||| : |||// \ /// / _||||| -:- |||||- \ /// | | \\\ - /// | | /// | \_| ''\---/'' | | /// \ .-\__ `-` ___/-. / /// ___`. .' /--.--\ `. . __ /// ."" '< `.___\_<|>_/___.' >'"". /// | | : `- \`.;`\ _ /`;.`/ - ` : | | /// \ \ `-. \_ __\ /__ _/ .-` / / /// ======`-.____`-.___\_____/___.-`____.-'====== /// `=---=' /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /// Buddha Bless, No Bug ! /// #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <cstdlib> #include <queue> #include <stack> #include <vector> using namespace std; #define MAXN 100010 #define ll long long #define in(a) a=read() inline long long read()///读入数据 { long long x=0,f=1; char ch=getchar(); for(; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1; for(; isdigit(ch); ch=getchar()) x=x*10+ch-'0'; return x*f; } ll n, m, p, a[MAXN]; struct node { ll l, r, sum, mlz, plz; } tree[4*MAXN]; inline void build(long long i,long long l,long long r)///Contribution { Tree [I] .L = L; Tree [I] .r = R & lt; Tree [I] .mlz = . 1 ; Tree [I] .plz = 0 ; IF (L == R & lt) { Tree [I] .sum = a [L]% P; return ; } Long Long MID = (L + R & lt) >> . 1 ; build (I << . 1 , L, MID); /// left side section son contribution build (I << . 1 | . 1 , MID + . 1 , R & lt); /// right side section contribution son Tree [I] = .sum (Tree [I << . 1 ] + Tree .sum [I << . 1 | . 1 ] .sum)% P; /// parent node is equal to the right son of the left son and processing and return ; } inline void pushdown ( Long Long I) { Long Long K1 = Tree [I] .mlz, K2 = Tree [I] .plz; Tree [I << . 1 ] = .sum (Tree [I << . 1 ] + K1 * K2 * .sum (Tree [I << . 1 ] .r-Tree [I << . 1 ] .L + . 1 ))% P; /// (left son value) is equal to (the value of the left son) * (mlz parent node) + (plz parent node) * (son left the control interval) Tree [i << 1 | 1] = .sum (Tree [I << . 1 | . 1 ] .sum * K1 + K2 * (Tree [I << . 1 | . 1 ] .r-Tree [I << . 1 | . 1 ] .L + . 1 ))% P ; /// (value of the right son) is equal to (the value of the right son) * (MLZ parent node) + (plz parent node) * (the right son control section) Tree [I << . 1 ] = .mlz (Tree [I << . 1 ] .mlz K1 *)% P; /// the parent node of the left son passed mlz Tree [I << . 1 | . 1 ] = .mlz (Tree [I << . 1 | . 1 ] * K1 .mlz)% P; /// the parent node of the right son passed mlz Tree [I << . 1 ] = .plz (Tree [I << . 1 ] .plz * K1 + K2)% P; // /(Left son plz) equal to (left son plz) * (parent mlz) + (parent plz), that is, look at this point how much added Tree [i << 1 | 1 ] .plz = (Tree [i << . 1 | . 1 ] .plz * K1 + K2)% P; /// (right son PLZ) equals (right son plz) * (parent mlz) + (parent plz), that is, look at this point plus how much the Tree [I] .plz = 0 ; Tree [I] .mlz = . 1 ; return ; } inline void MUL ( Long Long I, Long Long L, Long Long R & lt, Long Long K) { IF (Tree [I ] .L> Tree && = L [I] .r <= R & lt) ///If looking at the object range interval { Tree [I] .sum = (Tree [I] .sum * K)% P; /// Returns the value tree [i] .mlz = (tree [i] .mlz K *)% P; /// MLZ lazy labeled Tree [I] = .plz (Tree [I] .plz * K)% P; /// PLZ * K represents the interval added so many things (including prior to the addition portion) return ; } pushdown (I); IF (Tree [I << . 1 ] .r> = L) MUL (I << . 1 , L, R & lt, K); /// If you are looking interval in the left part of his son, the left son searches the IF (Tree [I << . 1 | . 1 ] .L <= R & lt) MUL (I << . 1 | . 1 , L, R & lt, K); /// If you are looking interval in the right part of his son, the right son searches the tree [i] .sum = (tree [i <<. 1 ] + Tree .sum [I << . 1 | . 1 ] .sum)% P; /// parent node sum equal to two sons sum return ; } inline void the Add ( Long Long I, Long Long L, Long Long R & lt , Long Long K) { IF (Tree [I] .L> Tree && = L [I] .r <= R & lt) /// If the interval in the object looking interval { Tree [I] .sum + = ( (Tree [I] .r-Tree [I] + .L . 1 ) * K)% P; /// (and the interval) equal to (and of the interval) + (the number of elements controlled interval) * K Tree [I] = .plz (Tree [I] .plz + k)% P; /// mark interval for each element that has been added k return ; } pushdown (I); IF (Tree [I << . 1 ] .r> = L) the Add (I << . 1 , L, R & lt, K); /// If you want to find the section in the left part of his son, searches the left son IF (Tree [I << . 1 | . 1 ] .L <= R & lt) the Add (I << . 1 | . 1 , L, R & lt, K); /// If you want to find the right son of the interval portion, to search for the right son Tree [I] = .sum (Tree [I << . 1 ] + Tree .sum [I << . 1 | . 1 ] .sum)% P; /// parent node sum equal to two sons sum return ; } inline LL Search ( Long Long I, Long Long L, Long Long R & lt) { IF (Tree [I] .r <L || Tree [I] .L> R & lt) return 0 ; /// If within this range is not looking for a range interval IF (Tree [I] .L> Tree && L = [I] .r <= R & lt) /// If the interval in the object looking interval { return Tree [I] .sum; /// directly back to this section and } pushdown (I); Long Long SUM = 0 ; IF (Tree [I << . 1 ] .r> = L) + SUM = Search (I << . 1 , L, R & lt); /// If you want to find the section in the left part of his son, to search left son IF (Tree [I << . 1 | . 1 ] .L <= R & lt) + SUM = Search (I << . 1| . 1 , L, R & lt); /// If you want to find the right son of the interval portion, the right son searches the return SUM =% P; } int main () { in (n-); in (m); in (P ); for ( int I = . 1 ; I <= n-; I ++ ) in (A [I]); Build ( . 1 , . 1 , n-); /// contribution for ( int I = . 1 ; I <= m; I ++ ) { LL FL; in (FL); IF (FL == . 1) { ll x, y, k; in(x); in(y); in(k); k%=p; mul(1, x, y, k);///乘 } if(fl==2) { ll x, y, k; in(x); in(y); in(k); k%=p; add(1, x, y, k);///加 } if(fl==3) { LL X, Y; in (X); in (Y); the printf ( " % LLD \ n- " , Search ( . 1 , X, Y)); /// interval lookup } } return 0 ; }