样例过了全WA求调...
查看原帖
样例过了全WA求调...
759274
Stevehim楼主2022/11/3 23:30

RT

add2表示乘法标记add2表示乘法标记
add表示加法标记add表示加法标记

#include <bits/stdc++.h>
#define maxn 1000000
using namespace std;
/*
更新(1)/删掉(2)的功能:
1:每个数都乘上一个数:其实就是加了一种标记?
1:取和需要模上一个数
其实只需要一个spread就可以了!!!
*/
typedef long long ll;
struct node {
    int l;
    int r;
    ll val;
    ll add;
    ll add2 = 1;
} a[maxn];
int num[maxn];
int n,m,p1;

ll binpow(ll a,ll b) { //手写快速幂
    ll ans = 1;
    while(b > 0) {
        if(b&1) {
            ans = ans * a;
        }
        a = a * a;
        b >>= 1;
    }
    return ans;
}

void build(int p, int l,int r) { //建树操作
    a[p].l = l;
    a[p].r = r;
    if(l == r) {
        a[p].val = num[l];
        return;
    }
    int mid = (l + r) / 2;
    build(p*2,l,mid); //为什么:因为建的是左子树,所以传l
    build(2*p+1,mid+1,r);
    a[p].val = a[2 * p].val + a[2 * p + 1].val;
}

void spread(int p) {
    if(a[p].add2||a[p].add) { //做到同时下传
        //注意:这里是对什么地方的lazytag进行操作呢?
        a[p*2].val = a[p*2].val*a[p].add2+a[p].add*(a[p*2].r-a[p*2].l+1);
        a[p*2+1].val = a[p*2+1].val*a[p].add2+a[p].add*(a[p*2+1].r-a[p*2+1].l+1);
        a[p*2].add2 *= a[p].add2;
        a[p*2+1].add2 *= a[p].add2;
        a[p*2].add*=a[p].add2,a[p*2].add+=a[p].add;
        a[p*2+1].add*=a[p].add2,a[p*2+1].add+=a[p].add;
        a[p].add2 = 1;
        a[p].add = 0;
    }
}


void change2(int p,int l,int r,int z) {
    if(l <= a[p].l && r>=a[p].r) {
        a[p].val = (ll)z * a[p].val;
        a[p].add2*=z;
        return;
    }
    spread(p);
    int mid = (a[p].r + a[p].l) / 2;
    if(l <= mid) {
        change2(p*2,l,r,z);
    }
    if(r > mid) {
        change2(p*2+1,l,r,z);
    }
    a[p].val = a[p*2].val + a[p*2+1].val;
}

void change(int p,int l,int r,int z) {
    if(l <= a[p].l && r >= a[p].r) { //已经包括了这段区间
        a[p].val += (long long)z*(a[p].r-a[p].l +1);
        a[p].add += z;
        return;
    }
    spread(p);
    int mid = (a[p].l + a[p].r) / 2;
    if(l <= mid) {
        change(p*2,l,r,z);
    }
    if(r > mid) {
        change(p*2+1,l,r,z);
    }
    a[p].val = a[p*2].val+a[p*2+1].val;
}

ll ask(int l, int r,int p) {
    if(l <= a[p].l && r >= a[p].r) {
        return a[p].val;
    }
    spread(p);
    ll ans = 0;
    int mid = (a[p].l + a[p].r) / 2;
    if(l <= mid) {
        ans += ask(l,r,p*2);
    }
    if(r > mid) {
        ans += ask(l,r,p*2+1);
    }
    return ans;
}

int main() {
    cin >>n >>m>>p1;
    for(int i = 1; i <= n; i++) {
        cin >>num[i];
    }
    build(1,1,n);
    int op;
    int x,y,k;
    for(int i = 0 ; i< m; i++) {
        cin >> op;
        if(op == 1) {
            cin >> x >> y >> k;
            change2(1,x,y,k);
        } else if(op == 2) {
            cin >> x>>y>>k;
            change(1,x,y,k);
        } else {
            cin >> x >> y;
            cout << ask(x,y,1) % p1 << endl;
        }
    }
    return 0;
}

2022/11/3 23:30
加载中...