2 条题解

  • 4
    @ 2025-7-9 15:59:07
    #include <bits/stdc++.h>
    using namespace std;
    int n,m;
    long long mod ;
    struct Mat{
        long long a11 = 1, a12 = 0, a21 = 0, a22 = 1;
        Mat operator*(const Mat &b) const{
            Mat res;
            res.a11 = (a11 * b.a11 + a12 * b.a21)%mod;
            res.a12 = (a11 * b.a12 + a12 * b.a22)%mod;
            res.a21 = (a21 * b.a11 + a22 * b.a21)%mod;
            res.a22 = (a21 * b.a12 + a22 * b.a22)%mod;
            return res;
        }
        bool isi(){
            return a11 == 1 && a12 == 0 && a22 == 1 && a21 == 0;
        }
    };
    long long a[100010];
    struct Segtree{
        long long tree[400040];
        Mat lazy[400040];
        void init(int size){
    
    
            build(1,1,size);
        }
        void build(int p,int l ,int r){
            if(l == r){
                tree[p] = a[l];
                lazy[p] = Mat();
                return;
            }
            int mid = (l + r) / 2;
            build(p * 2, l, mid);
            build(p * 2 + 1, mid + 1, r);
            tree[p] = (tree[p * 2] + tree[p * 2 + 1])%mod;
        }
        void pushdown(int p,int l,int r){
            if(!lazy[p].isi()){
                int mid = (l + r) / 2;
                tree[p*2] = (lazy[p].a11 * tree[p*2] + lazy[p].a12 * (mid - l + 1))%mod;
                tree[p*2+1] = (lazy[p].a11 * tree[p*2+1] + lazy[p].a12 * (r - mid))%mod;
                lazy[p*2] = lazy[p] * lazy[p*2];
                lazy[p*2+1] = lazy[p] * lazy[p*2+1];
                lazy[p] = Mat();
            }
        }
        void add(int p,int l,int r,int ql,int qr,int val){
            if(ql <= l && r <= qr){
                tree[p] = (tree[p] + val * (r-l+1)) % mod;
                Mat tmp;
                tmp.a11 = 1;
                tmp.a22 = 1;
                tmp.a12 = val;
                lazy[p] = tmp * lazy[p];
                return ;
            }
            pushdown(p,l,r);
            int mid = (l + r) / 2;
            if(ql <= mid){
                add(p * 2, l, mid, ql, qr, val);
            }
            if(mid < qr){
                add(p * 2 + 1, mid + 1, r, ql, qr, val);
            }
            tree[p] = (tree[p * 2] + tree[p * 2 + 1])%mod;
        }
        void mul(int p,int l,int r,int ql,int qr,int val){
            if(ql <= l && r <= qr){
                tree[p] = (tree[p] * val) % mod;
                Mat tmp;
                tmp.a11 = val;
                tmp.a22 = 1;
                lazy[p] = tmp * lazy[p];
                return ;
            }
            pushdown(p,l,r);
            int mid = (l + r) / 2;
            if(ql <= mid){
                mul(p * 2, l, mid, ql, qr, val);
            }
            if(mid < qr){
                mul(p * 2 + 1, mid + 1, r, ql, qr, val);
            }
            tree[p] = (tree[p * 2] + tree[p * 2 + 1])%mod;
        }
        long long query(int p,int l,int r,int ql,int qr){
            if(ql <= l && r <= qr){
                return tree[p];
            }
            pushdown(p,l,r);
            int mid = (l + r) / 2;
            long long res = 0;
            if(ql <= mid){
                res += query(p * 2, l, mid, ql, qr);
            }
            if(mid < qr){
                res += query(p * 2 + 1, mid + 1, r, ql, qr);
            }
            return res%mod;
        }
    };
    Segtree st;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
    
    //    freopen("test1.in","r",stdin);
    //    freopen("test1.out","w",stdout);
        // 6 4 10000000 1 2 3 4 5 6 2 2 6 4 3 1 4 2 1 5 2 3 2 5
        cin >> n >> m >> mod;
        for(int i = 1; i <= n; i++){
            cin >> a[i];
        }
        st.init( n);
        while(m--){
            int op;
            cin >> op;
            if(op == 1){
                int l,r,val;
                cin >> l >> r >> val;
                st.mul(1,1,n,l,r,val);
            }else if(op == 2){
                int l,r,val;
                cin >> l >> r >> val;
                st.add(1,1,n,l,r,val);
            }else if(op == 3){
                int l,r;
                cin >> l >> r;
                cout << st.query(1,1,n,l,r) << '\n';
            }
    
    //        for(int i = 1; i<= n; i++){
    //            cout << st.query(1,1,n,i,i) << ' ';
    //        }
    //        cout << endl;
        }
        return 0;
    }
    
    

    信息

    ID
    2432
    时间
    1000ms
    内存
    512MiB
    难度
    6
    标签
    递交数
    28
    已通过
    10
    上传者