社区讨论

Dalao帮帮忙WA

P3373【模板】线段树 2参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mi6z2og3
此快照首次捕获于
2025/11/20 13:10
4 个月前
此快照最后确认于
2025/11/20 13:10
4 个月前
查看原帖

我思路应该没错,但是只有 30Points,求Dalao帮忙找下Bug

CPP
#include<iostream>
#include<cstdio>
using namespace std;
const int size = 100005;
typedef long long ll;
#define ls i * 2
#define rs i * 2 + 1

ll p;
struct node {
    ll v, mul, add;
    // v为结点值,mul表示乘法lazytag,add为加法lazytag
} st[size * 4];
inline void push_up(int i) {
    st[i].v = (st[ls].v + st[rs].v) % p;
}
void build(int i,int l, int r) {
    st[i] = (node) {0, 1, 0};
    if(l == r) {
        scanf("%lld", &st[i].v);
        st[i].v %= p;
        return;
    } else {
        int mid = (l + r) / 2;
        build(ls, l, mid), build(rs, mid + 1, r);
        push_up(i);
    }
}
inline void push_down(int i,int l, int r) {
    int mid = (l + r) / 2;
    st[ls].v = (st[ls].v * st[i].mul + st[i].add * (mid - l + 1)) % p;
    st[rs].v = (st[rs].v * st[i].mul + st[i].add * (r - mid)) % p;
    
    st[ls].mul = (st[ls].mul * st[i].mul) % p;
    st[rs].mul = (st[rs].mul * st[i].mul) % p;
    
    st[ls].add = (st[ls].add * st[i].mul + st[i].add);
    st[rs].add = (st[rs].add * st[i].mul + st[i].add);
    
    st[i].mul = 1, st[i].add = 0;
}
// * update1
void update1(int i, int stdl, int stdr, int l, int r, ll k) {
    //printf("update1\n");
    if(r < stdl || l > stdr) 
        return;
    if(l <= stdl && r >= stdr) {
        st[i].v = (st[i].v * k) % p;
        st[i].mul = (st[i].mul * k) % p;
        st[i].add = (st[i].add * k) % p;
        return;
    }
    push_down(i, stdl, stdr);
    int mid = (stdl + stdr) / 2;
    update1(ls, stdl, mid, l, r, k);
    update1(rs, mid + 1, stdr, l, r, k);
    push_up(i);
}
// + update2
void update2(int i, int stdl, int stdr, int l, int r, ll k) {
    //printf("update2\n");
    if(r < stdl || l > stdr) 
        return;
    if(l <= stdl && r >= stdr) {
        st[i].add = (st[i].add + k) % p;
        st[i].v = (st[i].v + k * (stdr - stdl + 1)) % p;
        return;
    }
    push_down(i, stdl, stdr);
    int mid = (stdl + stdr) / 2;
    update2(ls, stdl, mid, l, r, k);
    update2(rs, mid + 1, stdr, l, r, k);
    push_up(i);
}

ll query(int i, int stdl, int stdr, int l, int r) {
    //printf("query\n");
    if(r < stdl || l > stdr) 
        return 0;
    if(l <= stdl && r >= stdr) 
        return st[i].v;
    push_down(i, stdl, stdr);
    int mid = (stdl + stdr) / 2;
    return (query(ls, stdl, mid, l, r) + query(rs, mid + 1, stdr, l, r)) % p;
}

int main() {
	int n, m;
    scanf("%d%d%lld", &n, &m, &p);
    build(1, 1, n);
    while(m--) {
        int man;
        scanf("%d", &man);
        if(man == 1) {
            int x, y;
            ll k;
            scanf("%d%d%lld", &x, &y, &k);
            //printf("check %d %d %lld\n", x, y, k);
            update1(1, 1, n, x, y, k);
        } else if(man == 2) {
            int x, y;
            ll k;
            scanf("%d%d%lld", &x, &y, &k);
            //printf("check %d %d %lld\n", x, y, k);
            update2(1, 1, n, x, y, k);
        } else {
            int x, y;
            scanf("%d%d", &x, &y);
            //printf("check %d %d\n", x, y);
            printf("%lld\n", query(1, 1, n, x, y));
        }
    }
    return 0;
}
略有借鉴第一篇题解

回复

3 条回复,欢迎继续交流。

正在加载回复...