Los template Valley P3373 [2] segment tree (tree line interval multiply, add intervals to find)

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

Input # 1
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
Output # 1
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 ; 
}

 

Guess you like

Origin www.cnblogs.com/RootVount/p/11293929.html