Submission #1268166

#TimeUsernameProblemLanguageResultExecution timeMemory
1268166rayan_bdAddk (eJOI21_addk)C++20
0 / 100
103 ms8372 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct segment_tree{
    vector<int> seg;
    int N;
    void init(int n){
        N = n;
        seg.resize(n * 6, 0);
    }
    void upd(int node, int start, int end, int idx, int val){
        if(start == end){
            seg[node] = val;
            return;
        }
        int mid = start + (end - start) / 2;
        if(idx <= mid) upd(node * 2 + 1, start, mid, idx, val);
        else upd(node * 2 + 2, mid + 1, end, idx, val);
        seg[node] = seg[node * 2 + 1] + seg[node * 2 + 2];
    }
    int query(int node, int start, int end, int l, int r){
        if(start > r || end < l) return 0;
        if(start >= l && end <= r) return seg[node];
        int mid = start + (end - start) / 2;
        return query(node * 2 + 1, start, mid, l, r)
             + query(node * 2 + 2, mid + 1, end, l, r);
    }
    void upd(int point, int val){
        upd(0, 1, N, point, val);
    }
    int query(int l, int r){
        return query(0, 1, N, l, r);
    }
} tr1, tr2, tr3;
signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);
    int n, k, q, t, l, r, m;
    cin >> n >> k;
    vector<int> a(n + 1, 0);
    for(int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    tr1.init(n + 5), tr2.init(n + 5), tr3.init(n + 5);
    for(int i = 1; i <= n; ++i){
        tr1.upd(i, a[i] * i);
        tr2.upd(i, a[i] * (n - i + 1));
        tr3.upd(i, a[i]);
    }
    auto get = [&](int l, int r, int xx) -> int{
        if(l > r) return 0; 
        return tr3.query(l, r) * xx;
    };
    cin >> q;
    while(q--){
        cin >> t;
        if(t == 1){
            vector<int> pos(k);
            for(auto &it : pos) cin >> it;
            // i1, i2, i3, i4
            // i2, i3, i4, i1
            int tmp = a[pos[0]];

            for(int i = 0; i < (int) pos.size() - 1; ++i){
                a[pos[i]] = a[pos[i + 1]];
                tr1.upd(pos[i], a[pos[i + 1]] * pos[i]);
                tr2.upd(pos[i], a[pos[i + 1]] * (n - pos[i] + 1));
                tr3.upd(pos[i], a[pos[i + 1]]);
            }

            a[pos.back()] = tmp;

            tr1.upd(pos.back(), tmp * pos.back());
            tr2.upd(pos.back(), tmp * (n - pos.back() + 1));
            tr3.upd(pos.back(), tmp);

        }else{
            cin >> l >> r >> m;
            // 1 2 3 4 5
            // 1 to m - 1
            // n - m + 2 to m
            int ans = 0;
            if(r - l + 1 == m){
                ans = tr3.query(l, r);
            }else{
                ans = get(m + l - 1, r - m + 1, m);
                int l1 = l, r1 = l + m - 2, l2 = r - m + 2, r2 = r;
                if(l2 == r1) l2 += 1;
                if(l1 <= r1) ans += tr1.query(l1, r1) - tr3.query(l1, r1) * (l1 - 1);
                if(l2 <= r2) ans += tr2.query(l2, r2) - tr3.query(l2, r2) * (n - r2);
               // cout << "check :- " << tr2.query(l2, r2) - tr3.query(l2, r2) * (n - r2) << endl;
            }

            cout << ans << "\n";
        }
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...