线段树板子出锅了,前来求助QwQ
查看原帖
线段树板子出锅了,前来求助QwQ
215734
红石小蝈楼主2020/8/18 09:39

如题,

#include <iostream>
#include <fstream>
using namespace std;
//#define DEBUG
ifstream fin("st+.in");
ofstream fout("st+.out");
typedef long long int llint;
typedef const int& cintr;
const int MAX = 250005;
///TODO
int mod;
class SegTree{
private:
    llint data[MAX<<1];
    llint lazyadd[MAX<<1];
    llint lazymul[MAX<<1];
    int n;
    #define lson (p<<1)
    #define rson ((p<<1)|1)
    void lazy(cintr p, cintr s, cintr e){
        if((lazymul[p] == 1 && lazyadd[p] == 0) || s == e)return;
        int m = (e + s)>>1;
        if(!lazymul[p])
            data[lson] = data[rson] =
            lazyadd[lson] = lazyadd[rson] =
            lazymul[lson] = lazymul[rson] = 0;
        else{
            data[lson] = (data[lson] * lazymul[p] % mod + lazyadd[p] * (m - s) % mod) % mod;
            data[rson] = (data[rson] * lazymul[p] % mod + lazyadd[p] * (e - m) % mod) % mod;
            lazyadd[lson] = (lazyadd[lson] * lazymul[p] + lazyadd[p]) % mod;
            lazyadd[rson] = (lazyadd[rson] * lazymul[p] + lazyadd[p]) % mod;
            lazymul[lson] = lazymul[lson] * lazymul[p] % mod;
            lazymul[rson] = lazymul[rson] * lazymul[p] % mod;
        }
        lazyadd[p] = 0;
        lazymul[p] = 1;
    }
    void mul(cintr l, cintr r, const llint& val, cintr s, cintr e, cintr p){// multiply val to [l, r)
        if(l <= s && e <= r){
            data[p] = data[p] * val % mod;
            lazymul[p] = lazymul[p] * val % mod;
            lazyadd[p] = lazyadd[p] * val % mod;
            return ;
        }
        int m = (s + e) >> 1;
        lazy(p, s, e);
        if(l < m)mul(l, r, val, s, m, lson);
        if(m < r)mul(l, r, val, m, e, rson);
        data[p] = (data[lson] + data[rson]) % mod;
    }
    void add(cintr l, cintr r, const llint& val, cintr s, cintr e, cintr p){// add val to the [l, r)
        if(l <= s && e <= r){
            data[p] = (data[p] + val * (e - s)) % mod;
            lazyadd[p] = (lazyadd[p] + val) % mod;
            return ;
        }
        int m = (s + e)>>1;
        lazy(p, s, e);
        if(l < m)add(l, r, val, s, m, lson);
        if(m < r)add(l, r, val, m, e, rson);
        data[p] = (data[lson] + data[rson]) % mod;
    }
    llint get(cintr l, cintr r, cintr s, cintr e, cintr p){//get [l, r)
        if(l <= s && e <= r)
            return data[p];
        int m = (s + e)>>1;
        lazy(p, s, e);
        return ((l < m?get(l, r, s, m, lson):0)+
                (m < r?get(l, r, m, e, rson):0)) % mod;
    }
    void build(llint* a, cintr l, cintr r, cintr p){// build the [l, r) interval
        lazymul[p] = 1;
        if(r - l == 1){
            data[p] = a[l];
            return;
        }
        int m = (l + r)>>1;
        build(a, l, m, lson);
        build(a, m, r, rson);
        data[p] = (data[lson] + data[rson])%mod;
    }
public:
    SegTree(int n):n(n){}
    void reset_n(int n){this->n = n;}
    void build(llint* a){build(a, 0, n, 1);}
    void add(cintr l, cintr r, const llint& val){add(l, r, val, 0, n, 1);}
    void mul(cintr l, cintr r, const llint& val){mul(l, r, val, 0, n, 1);}
    llint get(cintr l, cintr r){return get(l, r, 0, n, 1);}
    #undef lson
    #undef rson
}tree(MAX);
int n, m;
llint original[MAX];
int a, x, y, k;
#ifdef DEBUG
int time;
#endif
int main(){
    fin>>n>>m>>mod; tree.reset_n(n);
    for(int i = 0;i < n;i++)fin>>original[i];
    tree.build(original);
    while(m--){
        fin>>a;
        switch(a){
        case 1:
            fin>>x>>y>>k;
            tree.mul(x-1, y, k);
            break;
        case 2:
            fin>>x>>y>>k;
            tree.add(x-1, y, k);
            break;
        case 3:
            fin>>x>>y;
            #ifdef DEBUG
            fout<<"data "<<(++time)<<"\t";
            #endif
            fout<<tree.get(x-1, y)<<endl;
            break;
        default:
            break;
        }
    }
    return 0;
}

这代码只能得30pts, 大号的数据过不去QAQ--

2020/8/18 09:39
加载中...