zoukankan      html  css  js  c++  java
  • D. Constant Palindrome Sum

    You are given an array aa consisting of nn integers (it is guaranteed that nn is even, i.e. divisible by 22). All aiai does not exceed some integer kk.

    Your task is to replace the minimum number of elements (replacement is the following operation: choose some index ii from 11 to nn and replace aiai with some integer in range [1;k][1;k]) to satisfy the following conditions:

    • after all replacements, all aiai are positive integers not greater than kk;
    • for all ii from 11 to n2n2 the following equation is true: ai+ani+1=xai+an−i+1=x, where xx should be the same for all n2n2 pairs of elements.

    You have to answer tt independent test cases.

    Input

    The first line of the input contains one integer tt (1t1041≤t≤104) — the number of test cases. Then tt test cases follow.

    The first line of the test case contains two integers nn and kk (2n2105,1k21052≤n≤2⋅105,1≤k≤2⋅105) — the length of aa and the maximum possible value of some aiai correspondingly. It is guratanteed that nn is even (i.e. divisible by 22). The second line of the test case contains nn integers a1,a2,,ana1,a2,…,an (1aik1≤ai≤k), where aiai is the ii-th element of aa.

    It is guaranteed that the sum of nn (as well as the sum of kk) over all test cases does not exceed 21052⋅105 (n2105∑n≤2⋅105, k2105∑k≤2⋅105).

    Output

    For each test case, print the answer — the minimum number of elements you have to replace in aa to satisfy the conditions from the problem statement.

    Example
    input
    Copy
    4
    4 2
    1 2 1 2
    4 3
    1 2 2 1
    8 7
    6 1 1 7 6 3 4 6
    6 6
    5 2 6 1 3 4
    
    output
    Copy
    0
    1
    4
    2
    官方题解:

    It is obvious that if we fix the value of xx then there are three cases for the pair of elements:

    1. We don't need to change anything in this pair;
    2. we can replace one element to fix this pair;
    3. we need to replace both elements to fix this pair.

    The first part can be calculated easily in O(n+k)O(n+k), we just need to create the array of frequencies cntcnt, where cntxcntx is the number of such pairs (ai,ani+1)(ai,an−i+1) that ai+ani+1=xai+an−i+1=x.

    The second part is a bit tricky but still doable in O(n+k)O(n+k). For each pair, let's understand the minimum and the maximum sum we can obtain using at most one replacement. For the ii-th pair, all such sums belong to the segment [min(ai,ani+1)+1;max(ai,ani+1)+k][min(ai,an−i+1)+1;max(ai,an−i+1)+k]. Let's make +1+1 on this segment using prefix sums (make +1+1 in the left border, 1−1 in the right border plus one and then just compute prefix sums on this array). Let this array be prefpref. Then the value prefxprefx tells the number of such pairs that we need to replace at most one element in this pair to make it sum equals xx.

    And the last part can be calculated as n2prefxn2−prefx. So, for the sum xx the answer is (prefxcntx)+(n2prefx)2(prefx−cntx)+(n2−prefx)⋅2. We just need to take the minimum such value among all possible sums from 22 to 2k2k.

    There is another one solution that uses scanline, not depends on kk and works in O(nlogn)O(nlog⁡n) but it has no cool ideas to explain it here (anyway the main idea is almost the same as in the solution above).

    利用前缀和:make +1 in the left border, −1 in the right border plus one and then just compute prefix sums on this array

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
    #ifdef _DEBUG
        freopen("input.txt", "r", stdin);
    //    freopen("output.txt", "w", stdout);
    #endif
        
        int t;
        cin >> t;
        while (t--) {
            int n, k;
            cin >> n >> k;
            vector<int> a(n);
            for (auto &it : a) cin >> it;
            vector<int> cnt(2 * k + 1);
            for (int i = 0; i < n / 2; ++i) {
                ++cnt[a[i] + a[n - i - 1]];
            }
            vector<int> pref(2 * k + 2);
            for (int i = 0; i < n / 2; ++i) {
                int l1 = 1 + a[i], r1 = k + a[i];
                int l2 = 1 + a[n - i - 1], r2 = k + a[n - i - 1];
                assert(max(l1, l2) <= min(r1, r2));
                ++pref[min(l1, l2)];
                --pref[max(r1, r2) + 1];
            }
            for (int i = 1; i <= 2 * k + 1; ++i) {
                pref[i] += pref[i - 1];
            }
            int ans = 1e9;
            for (int sum = 2; sum <= 2 * k; ++sum) {
                ans = min(ans, (pref[sum] - cnt[sum]) + (n / 2 - pref[sum]) * 2);
            }
            cout << ans << endl;
        }
        
        return 0;
    }
  • 相关阅读:
    UVALive 4730 Kingdom +段树和支票托收
    zoj 3537 Cake (凸包确定+间隔dp)
    SVN在branch兼并和游戏patch(1)
    拍卖倒计时
    java基金会成立
    HDU1532 Drainage Ditches 【最大流量】
    leetcode-WordLadder
    Andriod Studio科普文章——3.大约gradle常见问题插头
    android Graphics(三):区域(Range)
    android Graphics(二):路径及文字
  • 原文地址:https://www.cnblogs.com/dealer/p/12752402.html
Copyright © 2011-2022 走看看