Los template Valley P3373 [2] segment tree problem solution

P3373 [template] segment tree 2

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)

[Thinking]

Tree line
most of the places and the tree line is 1 This question is like
I just said here about different places

[Modulo]

In each there is addition or multiplication with a
local operation related to the mold can have a mold look like

[Multiplication and addition]

The original segment tree template which has a lazy
it is because the addition of this operation
now has both addition and multiplication operation
would open two similar things like lazy storage

Modify lazy mark]

In addition lazy modify mark when he modified like normal
but modified multiplication when to die
because the front may have been added to the number
we still need to modify even with the addition of the mark with the look lazy
because the front had been added to a number of
now it is
(a + b)
this time, if multiplied by a number c
(a + b) * c + BC = AC
a by the c, lazy also labeled by the addition of so to modify the mark c in addition

[Complete code]

#include<iostream>
#include<cstdio>
#define int long long
#define lson (k << 1)
#define rson (k << 1 | 1)

using namespace std;
const int Max = 100005;
int read()
{
    int sum = 0,fg = 1;
    char c = getchar();
    while(c < '0' || c > '9')
    {
        if(c == '-')fg = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
    {
        sum = sum * 10 + c - '0';
        c = getchar(); 
    }
    return sum * fg;
}
int n,m,p;
int opl,opr,opx;
int ans;
struct node
{
    int l,r;
    int sum;
    int cheng,jia;
}a[Max << 2];

void build(int k,int l,int r)
{
    a[k].cheng = 1;
    a[k].jia = 0;
    a[k].l = l,a[k].r = r;
    if(l == r)
    {
        a[k].sum = read();
        a[k].sum %= p;
        return;
    }
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid + 1,r);
    a[k].sum = a[lson].sum + a[rson].sum;
    a[k].sum %= p;
}

void down(int k)
{
    if(a[k].jia != 0 || a[k].cheng != 1)
    {
        a[rson].cheng = (a[rson].cheng * a[k].cheng) % p;
        a[lson].cheng = (a[lson].cheng * a[k].cheng) % p;
        a[rson].jia = (a[rson].jia * a[k].cheng + a[k].jia) % p;
        a[lson].jia = (a[lson].jia * a[k].cheng + a[k].jia) % p;
        a[rson].sum = (a[rson].sum * a[k].cheng % p + a[k].jia * (a[rson].r - a[rson].l + 1)) % p;
        a[lson].sum = (a[lson].sum * a[k].cheng % p + a[k].jia * (a[lson].r - a[lson].l + 1)) % p;
        a[k].cheng = 1;
        a[k].jia = 0;
    }
}

void change1(int k)
{
    if(opl <= a[k].l && opr >= a[k].r)
    {
        a[k].cheng = (a[k].cheng * opx) % p;
        a[k].jia = (a[k].jia * opx) % p;
        a[k].sum = (a[k].sum * opx) % p;
        return;
    }
    down(k);
    int mid = (a[k].l + a[k].r) >> 1;
    if(opl <= mid)change1(lson);
    if(opr > mid)change1(rson);
    a[k].sum = (a[lson].sum + a[rson].sum) % p;
}

void change2(int k)
{
    if(opl <= a[k].l && opr >= a[k].r)
    {
        a[k].jia = (a[k].jia + opx) % p;
        a[k].sum = (a[k].sum + (a[k].r - a[k].l + 1) * opx % p) % p;
        return;
    }
    down(k);
    int mid = (a[k].l + a[k].r) >> 1;
    if(opl <= mid)change2(lson);
    if(opr > mid)change2(rson);
    a[k].sum = (a[lson].sum + a[rson].sum) % p;
} 

void query(int k)
{
    if(opl <= a[k].l && opr >= a[k].r)
    {
        ans += a[k].sum;
        ans %= p;
        return;
    }
    down(k);
    int mid = (a[k].l + a[k].r) >> 1;
    if(opl <= mid)query(lson);
    if(opr > mid)query(rson);
}

signed main()
{
    n = read(),m = read(),p = read();
    build(1,1,n);
    for(register int i = 1;i <= m;++ i)
    {
        int qwq = read();
        if(qwq == 1)
        {
            opl = read(),opr = read(),opx = read();
            change1(1);
        }
        else
        if(qwq == 2)
        {
            opl = read(),opr = read(),opx = read();
            change2(1);
        }
        else
        {
            opl = read(),opr = read();
            ans = 0;
            query(1);
            cout << ans % p << endl; 
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/acioi/p/11835706.html