1. 程式人生 > >維護序列 洛谷線段樹模板題2

維護序列 洛谷線段樹模板題2

hint reg ref org arch ucc search efi str

1104: 維護序列seq

Time Limit
3000 ms
Memory Limit
512072 KBytes
Judge
Standard Judge
Solved
71
Submit
234
Submit Status Star

Description

老師交給小可可一個維護數列的任務,現在小可可希望你來幫他完成。

有長為NN的數列,不妨設為a1,a2,,aNa1,a2,…,aN。有如下三種操作形式:

(1)把數列中的一段數全部乘一個值;

(2)把數列中的一段數全部加一個值;

(3)詢問數列中的一段數的和,由於答案可能很大,你只需輸出這個數模PP的值。

PS:本數據為純隨機數據,由菜god友情提供

Input Format

第一行兩個整數NN和P(1P1000000000)P(1≤P≤1000000000)。

第二行含有NN個非負整數,從左到右依次為a1,a2,,aNa1,a2,…,aN, (0ai1000000000,1iN)(0≤ai≤1000000000,1≤i≤N)。

第三行有一個整數MM,表示操作總數。

從第四行開始每行描述一個操作,輸入的操作有以下三種形式:

操作11:“1 t g c1 t g c”(不含雙引號)。表示把所有滿足tigt≤i≤g的aiai改為ai×c(1tgN,0c1000000000)ai×c(1≤t≤g≤N,0≤c≤1000000000)。

操作22:“2 t g c2 t g c”(不含雙引號)。表示把所有滿足tigt≤i≤g的aiai改為ai+c(1tgN,0c1000000000)

ai+c(1≤t≤g≤N,0≤c≤1000000000)。

操作33:“3 t g3 t g”(不含雙引號)。詢問所有滿足tigt≤i≤g的aiai的和模PP的值 (1tgN)(1≤t≤g≤N)。 同一行相鄰兩數之間用一個空格隔開,每行開頭和末尾沒有多余空格。

Output Format

對每個操作33,按照它在輸入中出現的順序,依次輸出一行一個整數表示詢問結果。

Sample Input

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

Sample Output

2
35
8

Hint

【樣例說明】

初始時數列為(1,2,3,4,5,6,7)

(1,2,3,4,5,6,7)。

經過第11次操作後,數列為(1,10,15,20,25,6,7)(1,10,15,20,25,6,7)。

對第22次操作,和為10+15+20=4510+15+20=45,模4343的結果是22。

經過第33次操作後,數列為(1,10,24,29,34,15,16)(1,10,24,29,34,15,16)

對第44次操作,和為1+10+24=351+10+24=35,模4343的結果是3535。

對第55次操作,和為29+34+15+16=9429+34+15+16=94,模4343的結果是88。

測試數據規模如下表所示

數據編號 1 2 3 4 5 6 7 8 9 10

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

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

Source

Ahoi2009
#include <stdio.h>
#define re register
typedef long long LL;

inline void read(LL &x) {
    x=0;char c=getchar();
    for(; 0>c || c>9; c=getchar());
    for(; 0<=c && c<=9; c=getchar()) x=(x<<1)+(x<<3)+(c^48);
}

struct node {
    LL sum;
    LL mul,add;
};

LL P;
LL a[100001];
node *s=new node[400004];

inline void build(LL id,LL l,LL r) {
    s[id].mul=1;
    s[id].add=0;
    if(l==r) {
        s[id].sum=a[l];
        return ;
    }
    LL mid=(l+r)>>1;
    build(id<<1,l,mid);
    build(id<<1|1,mid+1,r);
    s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P;
}


inline void pushdown(LL id,LL l,LL r) {
    LL mid=(l+r)>>1;
    s[id<<1].sum=((s[id<<1].sum*s[id].mul)+((mid-l+1)*s[id].add))%P;
    s[id<<1|1].sum=((s[id<<1|1].sum*s[id].mul)+((r-mid)*s[id].add))%P;
    s[id<<1].mul=(s[id<<1].mul*s[id].mul)%P;
    s[id<<1|1].mul=(s[id<<1|1].mul*s[id].mul)%P;
    s[id<<1].add=(s[id<<1].add*s[id].mul+s[id].add)%P;
    s[id<<1|1].add=(s[id<<1|1].add*s[id].mul+s[id].add)%P;
    s[id].add=0;
    s[id].mul=1;
}
inline void _mul(LL id,LL l,LL r,LL L,LL R,LL w) {
    if(L<=l && r<=R) {
        s[id].mul=(s[id].mul*w)%P;
        s[id].add=(s[id].add*w)%P;
        s[id].sum=(s[id].sum*w)%P;
        return ;
    }
    pushdown(id,l,r);
    LL mid=(l+r)>>1;
    if(L<=mid) _mul(id<<1,l,mid,L,R,w);
    if(R>mid) _mul(id<<1|1,mid+1,r,L,R,w);
    s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P;
}

inline void _add(LL id,LL l,LL r,LL L,LL R,LL w) {
    if(L<=l && r<=R) {
        s[id].add=(s[id].add+w)%P;
        s[id].sum=(s[id].sum+w*(r-l+1))%P;
        return ;
    }
    pushdown(id,l,r);
    LL mid=(l+r)>>1;
    if(L<=mid) _add(id<<1,l,mid,L,R,w);
    if(R>mid) _add(id<<1|1,mid+1,r,L,R,w);
    s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P;
}

inline LL search(LL id,LL l,LL r,LL L,LL R) {
    if(R<l || r<L) return 0;
    if(L<=l && r<=R) return s[id].sum;
    pushdown(id,l,r);
    LL mid=(l+r)>>1;
    return (search(id<<1,l,mid,L,R)+search(id<<1|1,mid+1,r,L,R))%P;
}

int main() {
    LL N;
    read(N),read(P);
    for(re LL i=1; i<=N; ++i) read(a[i]);
    build(1,1,N);
    LL M;
    read(M);
    for(re LL i=1; i<=M; ++i) {
        LL Q,T,G;
        read(Q),read(T),read(G);
        switch (Q) {
            case 1 :{
                LL C;
                read(C);
                _mul(1,1,N,T,G,C);
                break;
            }
            case 2 :{
                LL C;
                read(C);
                _add(1,1,N,T,G,C);
                break;
            }
            default :{
                printf("%lld\n",search(1,1,N,T,G));
                break;
            }
        }
    }
    delete[] s;
    return 0;
}

Ojbk

維護序列 洛谷線段樹模板題2