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

    Constant Palindrome Sum

    Constant Palindrome Sum 题目链接

    思路

    由于每一个数字的取值范围是([1, k]),所以对与每一对数字的和的取值应该在([2, 2k])

    对于每一对数字我们可以选择改变一个、改变两个或者一个都不改变。

    • 改变一个的时候,数值区域可以变成([min(a, b) + 1, max(a, b) + k])

    • 改变两个的时候,数值区域可以变成([2, min(a, b)]),和([max(a, b) + k + 1, 2k])

    • 一个都不变,其值只有可能是(a + b)

    我们定义三个数组

    • 1、num数组,记录的是下标为 ((a + b))的数对的个数。

    • 2、change1数组,记录的是改变一个数字的时候可取的区域相应的操作数,这里为了降低复杂度所以采用差分的形式,大致操作如下
      (change1[min(a, b) + 1]++)
      (change1[max(a, b) + k + 1]--)

    • 3、change2数组,记录的是改变两个数字对应的操作次数,其对应对change2数组的操作如下
      (change2[2] += 2,change2[min(a, b) + 1] -= 2)
      (change2[max(a, b) + k + 1] += 2,change2[2k + 1] -= 2)

    所以最后的答案就是当前答案操作一次的数量加上操作两次的数量减去当前答案的数值的数量

    也就是 (change1[i] + change2[i] - num[i])

    减去 (num[i]) 的操作相信大家应该明白,就是在
    ([min(a, b) + 1, max(a, b) + k]) 中包括了 (a + b)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 4e5 + 10;
    const int INF = 0x3f3f3f3f;
    int a[N], num[N], change1[N], change2[N], n, m;
    int main() {
        // freopen("in.txt", "r", stdin);
        int t;
        scanf("%d", &t);
        while(t--) {
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            for(int i = 0; i <= 2 * m + 5; i++)
                num[i] = change1[i] = change2[i] = 0;
            //所有和的可能性[2, 2m]
            for(int i = 1; i <= n / 2; i++) {
                num[a[i] + a[n - i + 1]]++;
                int l = min(a[i], a[n - i + 1]) + 1;
                int r = max(a[i], a[n - i + 1]) + m;
                //[l, r]只要改变一个数
                change1[l]++, change1[r + 1]--;
                //[2, l - 1] 和 [r + 1, 2m]改变两个数。
                change2[2] += 2, change2[l]-= 2;
                change2[r + 1] += 2;
            }
            for(int i = 3; i <= 2 * m + 5; i++) {
                // num[i] += num[i - 1];
                change1[i] += change1[i - 1];
                change2[i] += change2[i - 1];
            }
            // for(int i = 2; i <= 2 * m; i++) {
            //     printf("%d ", num[i]);
            // }
            // puts("");
            // for(int i = 2; i <= 2 * m; i++) {
            //     printf("%d ", change1[i]);
            // }
            // puts("");
            // for(int i = 2; i <= 2 * m; i++) {
            //     printf("%d ", change2[i]);
            // }
            // puts("");
            int ans = INF;
            for(int i = 2; i <= 2 * m; i++)
                ans = min(ans, change1[i] - num[i] + change2[i]);
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    "动作面板"组件:<action-sheet> —— 快应用组件库H-UI
    "浮动弹层"组件:<float-layout> —— 快应用组件库H-UI
    "幕帘"组件:<curtain> —— 快应用组件库H-UI
    "轻提示"组件:<toast> —— 快应用组件库H-UI
    "模态框"组件:<modal> —— 快应用组件库H-UI
    "同一行代码片段"组件:<code> —— 快应用组件库H-UI
    "电脑程序输出"组件:<samp> —— 快应用组件库H-UI
    "多行代码"组件:<pre> —— 快应用组件库H-UI
    "按键提示"组件:<kbd> —— 快应用组件库H-UI
    "变量赋值"组件:<var> —— 快应用组件库H-UI
  • 原文地址:https://www.cnblogs.com/lifehappiness/p/12802598.html
Copyright © 2011-2022 走看看