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;
    }
  • 相关阅读:
    [OAuth]基于DotNetOpenAuth实现Client Credentials Grant
    不走标准路的微软:少一个斜杠的URI Path
    远程服务器返回错误: (405) 不允许的方法
    SQL Server的差异备份还原
    Visual Studio的“Waiting for a required operation to complete...”问题
    解决“The remote certificate is invalid according to the validation procedure”问题
    基于Json.NET自己实现MVC中的JsonValueProviderFactory
    ASP.NET MVC 3升级至MVC 5.1的遭遇:“已添加了具有相同键的项”
    解决Android版Firefox字体显示过大的问题
    给IIS添加CA证书以支持https
  • 原文地址:https://www.cnblogs.com/dealer/p/12752402.html
Copyright © 2011-2022 走看看