Line tree - maintenance sequence

Maintenance sequence

The teacher gave Xiaoke a task to maintain the number sequence. Now Xiaoke hopes you can help him finish it.

There is a sequence with length of N, which may be set as a1,a2 aN.

There are three types of operation:

Multiply all the numbers in a sequence by one value;
Add a value to all the numbers in the sequence;
Ask the sum of a number in a sequence. Since the answer may be very large, you only need to output the value of the analog P.
Input format
Two integers N and P in the first line;

The second line contains N non negative integers, a1,a2 aN;

The third line has an integer M, which represents the total number of operations;

Starting from the fourth line, each line describes an operation. The input operation has the following three forms:

Operation 1:1 t g c, which means to change all ai satisfying t ≤ i ≤ g to ai × c;
Operation 2: 2 t g c, which means that all ai satisfying t ≤ i ≤ g is changed to ai+c;
Operation 3: 3T g, ask all ai's and module P's values that meet t ≤ i ≤ G.
Two adjacent numbers in the same line are separated by a space, and there is no extra space at the beginning and end of each line.

Output format
For each operation 3, in the order in which it appears in the input, the query results are output one by one.

Data range
1≤N,M≤1051≤N,M≤10^51≤N,M≤105
1≤t≤g≤N1≤t≤g≤N1≤t≤g≤N,
0≤c,ai≤1090≤c,a_i≤10^90≤c,ai​≤109,
1≤P≤1091≤P≤10^91≤P≤109
Input example:
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 example:
2
35
8
Exemplar interpretation
The initial sequence is {1,2,3,4,5,6,7};

After the first operation, the sequence is {1,10,15,20,25,6,7};

For the second operation, the sum is 10 + 15 + 20 = 45, and the result of module 43 is 2;

After the third operation, the sequence is {1,10,24,29,34,15,16};

For the fourth operation, the sum is 1 + 10 + 24 = 35, and the result of module 43 is 35;

For the fifth operation, the sum is 29 + 34 + 15 + 16 = 94, and the result of module 43 is 8.

Explanation:

We found that the way we first added and then multiplied was not easy. So write an expression to express it in polynomials. It's easy to deal with it by multiplying first and then adding.

#include <bits/stdc++.h>
#define int long long
using namespace std;
#define lson u<<1
#define rson u<<1|1
const int N=1e5+7;
int n,m,p;
int a[N];
struct Node
{
    int l,r;
    int sum,add,mul;
}tr[N<<2];
void pushup(Node &u,Node &l,Node &r)
{
    u.sum=(l.sum+r.sum)%p;
}
void pushup(int u)
{
    pushup(tr[u],tr[lson],tr[rson]);
}
void build(int u,int l,int r)
{
    if(l==r){
        tr[u]={l,l,a[l],0,1};
        return;
    }
    int mid=l+r>>1;
    tr[u]={l,r,0,0,1};
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(u);
}
void evu(Node &u,int add,int mul)
{
    u.sum=(1LL*u.sum*mul%p+(u.r-u.l+1)*add)%p;
    u.mul=(1LL*u.mul*mul)%p;
    u.add=(1LL*u.add*mul+add)%p;
}
void pushdown(int u)
{
    evu(tr[lson],tr[u].add,tr[u].mul);
    evu(tr[rson],tr[u].add,tr[u].mul);
    tr[u].add=0,tr[u].mul=1;
}
void modify(int u,int l,int r,int add,int mul){
//    cout<<u<<' '<<l<<' '<<r<<endl;
    if(tr[u].l>=l&&tr[u].r<=r){
        evu(tr[u],add,mul);
        return;
    }
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid) modify(lson,l,r,add,mul);
    if(r>mid) modify(rson,l,r,add,mul);
    pushup(u);
}
Node query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(r<=mid) return query(lson,l,r);
    else if(l>mid) return  query(rson,l,r);
    else{
        auto left=query(lson,l,mid);
        auto right=query(rson,mid+1,r);
        Node res;
        pushup(res,left,right);
        return res;
    }
}

signed main(){
    scanf("%lld%lld",&n,&p);
    for(int i=1;i<=n;i++) scanf("%lld",a+i);
    scanf("%lld",&m);
    build(1,1,n);
//    cout<<"---"<<endl;
    for(int i=1;i<=m;i++){
        int t; scanf("%lld",&t);
        if(t==1){
            int l,r,c;
            scanf("%lld%lld%lld",&l,&r,&c);
            modify(1,l,r,0,c);
//            cout<<"1"<<endl;
        }else if(t==2){
//            cout<<2<<endl;
            int l,r,c;
            scanf("%lld%lld%lld",&l,&r,&c);
            modify(1,l,r,c,1);
        }else{
//            cout<<3<<endl;
            int l,r; scanf("%lld%lld",&l,&r);
            printf("%lld\n",query(1,l,r).sum);
        }
    }
}
First article in the station
171 original articles published, 10 praised, 4731 visited
Private letter follow

Posted on Thu, 06 Feb 2020 03:31:12 -0500 by cgraz