Submission #1172843

#TimeUsernameProblemLanguageResultExecution timeMemory
1172843dbekarysAddk (eJOI21_addk)C++20
36 / 100
2097 ms4780 KiB
#include <iostream>
#include <vector>
using namespace std;

class SegmentTree {
private:
    vector<long long> tree;
    int n;

    void build(vector<int>& arr, int node, int start, int end) {
        if (start == end) {
            tree[node] = arr[start];
        } else {
            int mid = (start + end) / 2;
            build(arr, 2 * node, start, mid);
            build(arr, 2 * node + 1, mid + 1, end);
            tree[node] = tree[2 * node] + tree[2 * node + 1];
        }
    }

    void update(int node, int start, int end, int idx, int value) {
        if (start == end) {
            tree[node] = value;
        } else {
            int mid = (start + end) / 2;
            if (idx <= mid) {
                update(2 * node, start, mid, idx, value);
            } else {
                update(2 * node + 1, mid + 1, end, idx, value);
            }
            tree[node] = tree[2 * node] + tree[2 * node + 1];
        }
    }

    long long query(int node, int start, int end, int l, int r) {
        if (r < start || end < l) {
            return 0;
        }
        if (l <= start && end <= r) {
            return tree[node];
        }
        int mid = (start + end) / 2;
        long long left_sum = query(2 * node, start, mid, l, r);
        long long right_sum = query(2 * node + 1, mid + 1, end, l, r);
        return left_sum + right_sum;
    }

public:
    SegmentTree(vector<int>& arr) {
        n = arr.size();
        tree.resize(4 * n);
        build(arr, 1, 0, n - 1);
    }

    void update(int idx, int value) {
        update(1, 0, n - 1, idx, value);
    }

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

void circular_permute(vector<int>& arr, SegmentTree& seg_tree, vector<int>& indices) {
    int temp = arr[indices[0]];
    for (size_t i = 0; i < indices.size() - 1; ++i) {
        arr[indices[i]] = arr[indices[i + 1]];
        seg_tree.update(indices[i], arr[indices[i]]);
    }
    arr[indices.back()] = temp;
    seg_tree.update(indices.back(), temp);
}

long long sum_of_subsequences_sliding(vector<int>& arr, SegmentTree& seg_tree, int l, int r, int m) {
    // Initial subsequence sum
    long long current_sum = seg_tree.query(l, l + m - 1);
    long long result = current_sum;

    // Slide the window
    for (int i = l + 1; i <= r - m + 1; ++i) {
        current_sum -= arr[i - 1];
        current_sum += arr[i + m - 1];
        result += current_sum;
    }

    return result;
}

int main() {
    int N, K;
    cin >> N >> K;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i];
    }

    SegmentTree seg_tree(A);

    int Q;
    cin >> Q;

    while (Q--) {
        int type;
        cin >> type;

        if (type == 1) {
            vector<int> indices(K);
            for (int i = 0; i < K; ++i) {
                cin >> indices[i];
                indices[i]--; // Convert to 0-based index
            }
            circular_permute(A, seg_tree, indices);
        } else if (type == 2) {
            int l, r, m;
            cin >> l >> r >> m;
            l--; r--; // Convert to 0-based index
            cout << sum_of_subsequences_sliding(A, seg_tree, l, r, m) << endl;
        }
    }

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