萌新刚学OI,调的快要崩溃了……
查看原帖
萌新刚学OI,调的快要崩溃了……
203083
炎炎龙虾楼主2020/8/14 21:52

RT,复习线段树,但是连模板题都WA了,30分,但是别的帖子中的传递标记、取模、开long long等的可能导致30分的问题,我都注意到了,可是还是30分QwQ……

求助……

//File: P3373.cpp
//Author: yanyanlongxia
//Date: 2020/8/14
//
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct segment
{
    int l,r,sum,mtag,atag;//乘法记号,加法记号
}t[8000000];
int n,m,mo,a[1000000];
void build(int p,int l,int r) {
    t[p].l = l;
    t[p].r = r;
    t[p].mtag = 1;
    if (l == r) {
        t[p].sum = a[l] % mo;
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    t[p].sum = (t[p << 1].sum + t[p << 1 | 1].sum) % mo;
}
void spread(int p) {
    if (t[p].mtag != 1 || t[p].atag) {
        int mid = t[p].l + t[p].r >> 1;
        t[p << 1].sum = (t[p << 1].sum * t[p].mtag + t[p].atag * (mid - t[p].l + 1)) % mo;
        t[p << 1 | 1].sum = (t[p << 1 | 1].sum * t[p].mtag + t[p].atag * (t[p].r - mid)) % mo;
        t[p << 1].mtag = (t[p << 1].mtag * t[p].mtag) % mo;
        t[p << 1 | 1].mtag = (t[p << 1 | 1].mtag * t[p].mtag) % mo;
        t[p << 1].atag = (t[p << 1].atag * t[p].mtag + t[p].atag) % mo;
        t[p << 1 | 1].atag = (t[p << 1 | 1].atag * t[p].mtag + t[p].atag) % mo;
        t[p].atag = 0;
        t[p].mtag = 1;
    }
}
void mul(int p,int l,int r,int k) {
    if(t[p].mtag==0)
        t[p].mtag=1;
    if (l <= t[p].l && r >= t[p].r) {
        t[p].sum = (t[p].sum * k) % mo;
        t[p].mtag = (t[p].mtag * k) % mo;
        t[p].atag = (t[p].atag * k) % mo;
        return;
    }
    spread(p);
    int mid = t[p].l + t[p].r >> 1;
    if (l <= mid)
        mul(p << 1, l, r, k);
    if (r > mid)
        mul(p << 1 | 1, l, r, k);
    t[p].sum = (t[p << 1].sum + t[p << 1 | 1].sum) % mo;
}
void add(int p,int l,int r,int k) {
    if (l <= t[p].l && r >= t[p].r) {
        t[p].sum = (t[p].sum + k * (t[p].r - t[p].l + 1)) % mo;
        t[p].atag = (t[p].atag + k) % mo;
        return;
    }
    spread(p);
    int mid = t[p].l + t[p].r >> 1;
    if (l <= mid)
        add(p << 1, l, r, k);
    if (r > mid)
        add(p << 1 | 1, l, r, k);
    t[p].sum = (t[p << 1].sum + t[p << 1 | 1].sum) % mo;
}
int ask(int p,int l,int r) {
    if (l <= t[p].l && t[p].r <= r) {
        return t[p].sum % mo;
    }
    spread(p);
    int res = 0, mid = t[p].l + t[p].r >> 1;
    if (l <= mid)
        res = (res + ask(p << 1, l, r)) % mo;
    if (mid < r)
        res = (res + ask(p << 1 | 1, l, r)) % mo;
    return res % mo;
}
signed main() {
    int opt, x, y, k;
    scanf("%lld%lld%lld", &n, &m, &mo);
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &a[i]);
    }
    build(1, 1, n);
    for (int i = 1; i <= m; ++i) {
        scanf("%lld", &opt);
        if (opt == 1) {
            scanf("%lld%lld%lld", &x, &y, &k);
            mul(1, x, y, k);
        }
        if (opt == 2) {
            scanf("%lld%lld%lld", &x, &y, &k);
            add(1, x, y, k);
        }
        if (opt == 3) {
            scanf("%lld%lld", &x, &y);
            printf("%lld\n", ask(1, x, y));
        }
    }
    return 0;
}

2020/8/14 21:52
加载中...