牛客挑战赛39 C 牛牛的等差数列(线段树)(*)

题目链接
牛客挑战赛39 C 牛牛的等差数列(线段树)(*)_第1张图片
牛客挑战赛39 C 牛牛的等差数列(线段树)(*)_第2张图片

#include
#define ll long long
using namespace std;
const int maxn = 2e5 + 50;
int val[maxn];
ll a[maxn<<2], d[maxn<<2];
ll sum[maxn<<2];
const int mod = 3*5*7*11*13*17*19*23;
void build(int rt, int l, int r){
    if(l == r) {
        scanf("%lld",&sum[rt]);
        return;
    }
    int mid = (l+r)>>1;
    build(rt<<1, l, mid);
    build(rt<<1|1, mid+1, r);
    sum[rt] = (sum[rt<<1] + sum[rt<<1|1])%mod;
}
void down(int node, int L, int R){
    if(a[node] == 0 && d[node] == 0) return;
    int m = (L+R)>>1;
    a[node*2]=(a[node*2]+a[node])%mod;
    a[node*2+1]=(a[node*2+1]+a[node]+1LL*(m-L+1)*d[node])%mod;
    d[node*2]=(d[node*2]+d[node])%mod;
    d[node*2+1]=(d[node*2+1]+d[node])%mod;
    sum[node*2]=(sum[node*2]+a[node]*(m-L+1)+(1LL*(m-L)*(m-L+1)/2)*d[node])%mod;
    sum[node*2+1]=(sum[node*2+1]+a[node]*(R-m)+(1LL*(R-m)*(m+1-L+R-L)/2)*d[node])%mod;
    a[node]=0;d[node]=0;
}
void update(int rt, int L, int R, int x, int y, int k, int dd){
    if(L>=x&&R<=y){
        sum[rt]=(sum[rt]+1LL*(R-L+1)*k+(1LL*(L+R-x-x)*(R-L+1)/2)*dd)%mod;
        d[rt]=(d[rt]+dd)%mod;
        a[rt]=(a[rt]+k+1LL*(L-x)*dd)%mod;
        return;
    }
    down(rt, L, R);
    int mid = (L+R)>>1;
    if(x <= mid) update(rt<<1, L, mid, x, y, k, dd);
    if(y > mid) update(rt<<1|1, mid+1, R, x, y, k, dd);
    sum[rt] = (sum[rt<<1] + sum[rt<<1|1])%mod;
    return;
}
int qry(int rt, int l, int r, int L, int R, int c){
    if(L <= l && r <= R) return sum[rt]%c;
    int ans = 0;
    int mid = (l+r)>>1;
    down(rt, l, r);
    if(L <= mid) ans += qry(rt<<1, l, mid, L, R, c);
    if(R > mid) ans += qry(rt<<1|1, mid+1, r, L, R, c);
    return ans%c;
}
int main()
{
    int n; scanf("%d", &n);
    build(1,1,n);
    int q; scanf("%d", &q);
    while(q--){
        int op; scanf("%d", &op);
        if(op == 1){
            int l, r, fi, se;
            scanf("%d%d%d%d", &l, &r, &fi, &se);
            update(1, 1, n, l, r, fi, se);
        }else{
            int l, r, m; scanf("%d%d%d", &l, &r, &m);
     
            printf("%d\n", qry(1, 1, n, l, r, m));
        }
    }
}

你可能感兴趣的:(线段树)