线段树求调,玄关
查看原帖
线段树求调,玄关
856179
LiuQJun_271119楼主2023/9/24 19:26

RT,在 oiwiki 自学线段树,想打线段树,结果给我打挂了 QAQ

代码如下:

#include<bits/stdc++.h>

const int N = 1e5;

struct tree{
    int sum, add, mul;
}tr[4 * N + 5];
int n, q, m, a[N + 5];

void pushup(int x){tr[x].sum = (tr[x << 1].sum + tr[x << 1 | 1].sum) % m;}

void build(int l, int r, int x){
    tr[x].add = 0; tr[x].mul = 1;
    if(l == r){
        tr[l].sum = a[l];
        return;
    }
    int mid = l + r >> 1;
    build(l, mid, x << 1);
    build(mid + 1, r, x << 1 | 1);
    pushup(x);
}

void pushdown(int s, int t, int x){
    int mid = s + t >> 1;
    tr[x << 1].sum = (tr[x << 1].sum * tr[x].mul + tr[x].add * (mid - s + 1)) % m;
    tr[x << 1| 1].sum = (tr[x << 1 | 1].sum * tr[x].mul + tr[x].add * (t - mid)) % m;
    if(s != mid) tr[x << 1].add = (tr[x << 1].add * tr[x].mul + tr[x].add) % m, tr[x << 1].mul = tr[x << 1].mul * tr[x].mul % m;
    if(mid + 1 != t) tr[x << 1 | 1].add=(tr[x << 1 | 1].add * tr[x].mul + tr[x].add) % m, tr[x << 1 | 1].mul = tr[x << 1 | 1].mul * tr[x].mul % m;
    tr[x].add = 0; tr[x].mul = 1;
}

void update1(int l, int r, int s, int t, int x, int c){
    if(l <= s&&t <= r){
        tr[x].sum = (tr[x].sum + c * (t - s + 1)) % m;
        tr[x].add = (tr[x].add + c) % m;
        return;
    }
    int mid = s + t >> 1;
    pushdown(s, t, x);
    if(l <= mid) update1(l, r, s, mid, x << 1, c);
    if(r > mid) update1(l, r, mid + 1, t, x << 1 | 1, c);
    pushup(x);
}

void update2(int l,int r,int s,int t,int x,int c){
    if(l <= s&&t <= r){
        tr[x].sum = tr[x].sum * c % m;
        tr[x].add = tr[x].add * c % m;
        tr[x].mul = tr[x].mul * c % m;
        return;
    }
    int mid = s + t >> 1;
    pushdown(s, t, x);
    if(l <= mid) update2(l, r, s, mid, x << 1, c);
    if(r > mid) update2(l, r, mid + 1, t, x << 1 | 1, c);
    pushup(x);
}

int ask(int l, int r, int s, int t, int x){
    if(l <= s&&t <= r) return tr[x].sum % m;
    int mid = s + t >> 1;
    pushdown(s, t, x);
    int res = 0;
    if(l <= mid) res = (res + ask(l, r, s, mid, x << 1)) % m;
    if(r > mid) res = (res + ask(l, r, mid + 1, t, x << 1 | 1)) % m;
    return res % m;
}

int main(){
    scanf("%d%d%d", &n, &q, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, n, 1);
    while(q--){
        int cz, x, y; scanf("%d%d%d", &cz, &x, &y);
        if(cz == 3) printf("%d\n", ask(x, y, 1, n, 1) % m);
        else{
            int k; scanf("%d", &k);
            if(cz == 1) update1(x, y, 1, n, 1, k);
            else update2(x, y, 1, n, 1, k);
        }
    }
}

样例没过,找了好久找不出错。救救本蒟蒻吧~

(好像要开 longlong,但先解决我样例没过的问题吧)

2023/9/24 19:26
加载中...