2023 ICPC 江西省赛K. Split

K. Split

time limit per test: 3 seconds

memory limit per test: 512 megabytes

You are given a positive integer n and a non-increasing sequence ai of length n , satisfying ∀i∈[1,n−1],a_{i}\geq a_{i+1}.

Then, you are given a positive integer m, which represents the total number of operations.

There are two types of operations. The first type gives an integer x satisfying 1<x<n and changes a_{x} to a_{x-1}+a_{x+1}-a_{x}.

The second type is query operation and gives an integer k . Assuming the sequence is divided into k segments, and the length of each segment must be at least 1. The value of a segment is defined as the difference between the maximum element and the minimum element of the segment. You should print the mininum sum of the values of the k segments for all possible ways to divide the sequence into k segments.

Specifically, for each operation, you will be given the type of the operation first. If it is 0, it means the first type of operation, and if it is 1, it means the second type of operation. For the first type of operation, you will then be given a positive integer x. For the second type of operation, you will then be given a positive integer k.

Input

The first line contains a positive integer nn (3≤n≤10^{6}), representing the length of the sequence.

The second line contains nn positive integers a1,a2,...,an (1≤ai≤10^{9}).

The third line contains a positive integer mm (1≤m≤10^{6}), representing the total number of operations.

Next mm lines, each line containing either "0 x" (1<x<n) or "1 k" (1≤k≤n), denoting an operation.

Output

Print q lines where the i-th line contains one integer — the answer for the i-th query operation.

Example

Input

5
30 20 18 13 2
3
1 2
0 3
1 3

Output

17
7

【思路分析】

差分。显然本题答案为整序列最大值-整序列最小值-(k-1)个最大差分和,对于操作1,显然不会影响差分数组最大k个数的取值,仅会使差分数组中相邻元素改变顺序。那么我们sort差分数组,用后缀和记录差分和,那么对于每个操作2,我们只需要O(1)的时间复杂度。

由于需要sort,整体的时间复杂度为O(nlogn)。

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <cmath>
#include <algorithm>
#include <climits>
#include <stack>
#include <cstring>
#include <iomanip>
#include <set>
#include <queue>

#define i64 long long

using namespace std;

void solve() {
    i64 n;
    cin >> n;
    i64 a[n + 1];
    for (int i = 1; i <= n; ++i) cin >> a[i];
    i64 m, op, tmp;
    i64 diff[n - 1];
    for (int i = 1; i < n; ++i) diff[i - 1] = a[i] - a[i + 1];
    sort(diff, diff + n - 1);
    cin >> m;
    i64 suf[n], suff = 0;
    suf[n - 1] = 0;
    for (int i = n - 2; i >= 0; --i) {
        suf[i] = diff[i] + suff;
        suff = suf[i];
    }
    while (m--) {
        cin >> op >> tmp;
        if (op == 0) a[tmp] = a[tmp - 1] + a[tmp + 1] - a[tmp];
        else {
            i64 total = suf[n - tmp];
            cout << a[1] - a[n] - total << endl;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
//    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值