제출 #1354857

#제출 시각아이디문제언어결과실행 시간메모리
1354857khaiiAddk (eJOI21_addk)C++20
56 / 100
466 ms12664 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mid (l + r) / 2
#define lc pos * 2
#define rc pos * 2 + 1

struct segtree{
    int n;
    vector<int> seg, seg123, seg321;

    // segtree(int n, const vector<int> &a) : n(n), seg(4 * n + 1), seg123(4 * n + 1), seg321(4 * n + 1){
    //     build(1, 1, n, a);
    // }

    // segtree(){};

    void assign(int x, const vector<int> &a){
        n = x;
        seg.assign(4 * n + 1, 0);
        seg123.assign(4 * n + 1, 0);
        seg321.assign(4 * n + 1, 0);
        build(1, 1, n, a);
    }

    void build(int pos, int l, int r, const vector<int> &a){
        // cout << pos << " " << l << " " << r << endl;
        if(l == r){
            seg[pos] = a[l];
            seg123[pos] = a[l];
            seg321[pos] = a[l];
            return;
        }

        build(lc, l, mid + 0, a);
        build(rc, mid + 1, r, a);

        seg[pos] = seg[lc] + seg[rc];
        seg123[pos] = seg123[lc] + seg123[rc] + seg[rc] * (mid - l + 1);
        seg321[pos] = seg321[lc] + seg321[rc] + seg[lc] * (r - mid);
    }

    void update(int pos, int l, int r, int idx, int val){
        if(l == r){
            seg[pos] = val;
            seg123[pos] = val;
            seg321[pos] = val;
            return;
        }

        if(idx <= mid)  update(lc, l, mid + 0, idx, val);
        else            update(rc, mid + 1, r, idx, val);

        seg[pos] = seg[lc] + seg[rc];
        seg123[pos] = seg123[lc] + seg123[rc] + seg[rc] * (mid - l + 1);
        seg321[pos] = seg321[lc] + seg321[rc] + seg[lc] * (r - mid);
    }

    void update(int idx, int val){update(1, 1, n, idx, val);}

    int query(int pos, int l, int r, int ql, int qr){
        // cout << "query : " << pos << " " << l << " " << r << endl;
        if(r < ql || qr < l) return 0;
        if(ql <= l && r <= qr) return seg[pos];

        return query(lc, l, mid + 0, ql, qr) 
             + query(rc, mid + 1, r, ql, qr);
    }

    int query(int l, int r){return query(1, 1, n, l, r);}

    int query123(int pos, int l, int r, int ql, int qr){
        if(r < ql || qr < l) return 0;
        if(ql <= l && r <= qr) return seg123[pos] + seg[pos] * (l - ql);

        return query123(lc, l, mid + 0, ql, qr) 
             + query123(rc, mid + 1, r, ql, qr);
    }

    int query123(int l, int r){return query123(1, 1, n, l, r);}

    int query321(int pos, int l, int r, int ql, int qr){
        if(r < ql || qr < l) return 0;
        if(ql <= l && r <= qr) return seg321[pos] + seg[pos] * (qr - r);

        return query321(lc, l, mid + 0, ql, qr) 
             + query321(rc, mid + 1, r, ql, qr);
    }

    int query321(int l, int r){return query321(1, 1, n, l, r);}
};

segtree seg;
int n, k;

int query(int l, int r, int m){
    int ans = 0;

    if(l == r) return seg.query(l, r);

    ans += seg.query123(l, min(r - m + 1, l + m - 1));
    ans += seg.query321(max(l + m - 1, r - m + 1), r);
    // if(m == 1) ans = 0;
    ans += seg.query(min(r - m + 1, l + m - 1) + 1, max(l + m - 1, r - m + 1) - 1) * min(m, (r - l + 1 - m + 1));

    return ans;
}

void debug(int n){
    // cout << seg.query123(3, 4) << endl;
    // for(int i = 1; i <= n; i++) cout << seg.query(i, i) << " " ;
    // cout << endl;
}

void update(const vector<int> p, const vector<int> a){
    int ptr = p.size();

    for(int i = 0; i < ptr; i++){
        seg.update(p[i], a[p[(i + 1) % ptr]]);
    }
    debug(n);
}

signed main(){
    cin >> n >> k;

    vector<int> a(n + 1);
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }

    seg.assign(n, a);

    debug(n);

    int q;
    cin >> q;

    int l, r, m, tipe;
    vector<int> p(k);
    while(q--){
        cin >> tipe;

        if(tipe == 1){
            for(int i = 0; i < k; i++){
                cin >> p[i];
            }

            update(p, a);
        }

        if(tipe == 2){
            cin >> l >> r >> m;
            cout << query(l, r, m) << endl;
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...