Luo Gu P2023 [AHOI2009] maintenance sequence problem solution

P2023 [AHOI2009] maintenance sequence

Title Description

The teacher handed a small cocoa series of maintenance tasks, and now you want to help small cocoa him complete. N is the number of columns long, it may set a1, a2, ..., aN. There are three operational form as follows:
(1) the period of the number of columns in all multiplying a value;
(2) the period of the number of columns in all plus a value;
(3) asks the number of columns in a number of period and, since the answer may great, you only need to output the value of the digital-analog P.

Input Format

The first line of two integers N and P (1≤P≤1000000000).
The second line contains N non-negative integer, from left to right a1, a2, ..., aN, (0≤ai≤1000000000,1≤i≤N).
The third line has an integer M, represents the total number of operations.
Starting from the fourth row of each row describes an operation, the operation input of the following three forms:
Operation 1: "1 tgc" (without quotation marks). It represents all of the ai to meet t≤i≤g ai × c (1≤t≤g≤N, 0≤c≤1000000000) .
Operation 2: "2 tgc" (without quotation marks). Represents all of the ai t≤i≤g to satisfy ai + c (1≤t≤g≤N, 0≤c≤1000000000) .
Operation 3: "3 tg" (without quotation marks). All values satisfy the query and t≤i≤g P ai of a mold (1≤t≤g≤N).
The same line separated by a space between adjacent two numbers, no extra spaces at the end and beginning of each line.

Output Format

3, in the order it appears in the input, sequentially outputs each operating line represents an integer result of the inquiry.

Sample input and output

Input # 1

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

Output # 1

2
35
8

Description / Tips

[Sample Description]

Initially as the number (1,2,3,4,5,6,7).

After the first operation, as the number (1,10,15,20,25,6,7).

Of the second operation, and to 10 + 15 + 20 = 45, die 43 is 2 results.

After the third operation, as the number (1,10,24,29,34,15,16}

The first four runs, and 1 + 10 + 24 = 35, die 43 is 35 results.

A fifth operations, and 29 + 34 + 15 + 16 = 94, die 43 is 8 results.

The size of the test data in the following table

Data No. 12345678910

N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

Source: Ahoy 2009

[Thinking]

Tree line
segment tree 2 input sequence can change it out ,,,,, A
template tree line to see if 2 like
I am only here to say a few error-prone or hard to understand

[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;
}
struct node
{
    int l,r;
    int sum;
    int cheng,jia;
}a[Max << 2];
int n,m,p;
int ans;
int opl,opr,opx;
void build(int k,int l,int r)
{
    a[k].l = l,a[k].r = r;
    a[k].cheng = 1;
    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;
    return;
}

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

void change1(int k)
{
    if(opl <= a[k].l && opr >= a[k].r)
    {
        a[k].cheng *= opx;
        a[k].cheng %= p;
        a[k].jia *= opx;
        a[k].jia %= 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;
    a[k].sum %= p;
    return;
}

void change2(int k)
{
    if(opl <= a[k].l && opr >= a[k].r)
    {
        a[k].jia += opx;
        a[k].jia %= p;
        a[k].sum += (a[k].r - a[k].l + 1) * opx;
        a[k].sum %= 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;
    a[k].sum %= p;
    return;
}

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);
    return;
}

signed main()
{
    n = read(),p = read();
    build(1,1,n);
    m = read();
    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/11843305.html