跳转至

B. Artistic Balance Tree

时间限制:1.5 秒
内存限制:256 MB

问题描述

在学习了艺术平衡树之后,Lizhou 遇到了以下问题。

你有一个由 n 个整数组成的数组 a。你需要按顺序对 a 执行恰好 m 次操作。每次操作包含两个步骤。具体地,在第 i 次操作中,你会得到一个整数 x_i,然后你需要:

  1. 首先,选择一个中心下标 u 和一个非负长度 y,使得区间 [u-y, u+y] 完全落在 [1, n] 内(即 u-y \ge 1u+y \le n)。对于每个 1 \le i \le y,交换元素 a_{u-i}a_{u+i}
  2. 然后,标记下标 x_i 处的元素。如果该元素已经被标记,则什么也不做。注意,标记是打在元素上的,而不是打在位置上的。这意味着如果将来某次操作将该元素与其他元素交换,标记仍会跟随该元素。

在执行完所有 m 次操作后,你的任务是找到所有未标记元素最小可能总和

输入格式

每个测试包含多个测试用例。第一行包含整数 t1 \le t \le 10^4),表示测试用例的数量。接下来是每个测试用例的描述。

每个测试用例的第一行包含两个整数 nm1 \le n, m \le 10^5)——数组 a 的长度和操作次数。

第二行包含 n 个整数 a_1, a_2, \dots, a_n-10^9 \le a_i \le 10^9)——数组 a 的元素。

第三行包含 m 个整数 x_1, x_2, \dots, x_m1 \le x_i \le n)——每次操作中要标记的位置下标。

保证所有测试用例的 n 之和不超过 10^5
保证所有测试用例的 m 之和不超过 10^5

输出格式

对于每个测试用例,输出一个整数——所有操作结束后未标记元素的最小可能总和。

样例输入

6
7 4
1 2 3 4 5 6 7
1 2 3 4
7 4
1 -2 3 4 -5 -6 -7
7 6 5 4
7 5
21 -45 234 -8 423 12 -987
6 6 6 6 6
7 5
-21 45 -234 8 -423 -12 987
7 7 7 7 7
7 3
-1 2 -3 4 5 6 7
1 2 3
7 3
-1 -2 -3 -4 -5 -6 -7
1 2 3

样例输出

6
-20
-362
-637
2
-25

样例说明

第一个测试用例:一种最优操作序列如下:

  • 选择中心 u = 4,长度 y = 3,数组变为 [7,6,5,4,3,2,1]。然后标记元素 a_1 = 7
  • 选择中心 u = 1,长度 y = 0,数组不变。然后标记元素 a_2 = 6
  • 选择中心 u = 1,长度 y = 0,数组不变。然后标记元素 a_3 = 5
  • 选择中心 u = 1,长度 y = 0,数组不变。然后标记元素 a_4 = 4

最终未标记的元素是 1, 2, 3,总和为 1 + 2 + 3 = 6

第二个测试用例:一种最优操作序列如下:

  • 选择中心 u = 4,长度 y = 3,数组变为 [-7,-6,-5,4,3,-2,1]。然后标记元素 a_7 = 1
  • 选择中心 u = 5,长度 y = 1,数组变为 [-7,-6,-5,-2,3,4,1]。然后标记元素 a_6 = 4
  • 选择中心 u = 1,长度 y = 0,数组不变。然后标记元素 a_5 = 3
  • 选择中心 u = 5,长度 y = 1,数组变为 [-7,-6,-5,4,3,-2,1]。然后标记元素 a_4 = 4

未标记的元素是 -2, -5, -6, -7,总和为 (-2) + (-5) + (-6) + (-7) = -20

AC 代码

  • 很有意思的奇偶 位置转换题目,需要看清题目的本质就是奇偶位置互不影响
  • 然后我们给奇偶分开讨论
  • 单独对于奇数,我们需找到所有大于零的数,然后尽量删了,如果大于零的数多,那就尽量删,否则就只删大于零的 ,因为可以通过交换做到一直标记一个数
  • 当然还需要一定的特判,正常来说是不删负数,但是必须标记一个负数的时候,我们就标记最小的,写一个判断
    // Problem: CF 2222 B
    // Contest: Codeforces - Spectral::Cup 2026 Round 1 (Codeforces Round 1094, Div. 1 + Div. 2)
    // URL: https://codeforces.com/contest/2222/problem/B
    // Memory Limit: 256 MB
    // Time Limit: 1500 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    
    void fun(vector<int>& p){
        sort(p.begin(),p.end());
        //p.erase(unique(p.begin(),p.end()),p.end());
        reverse(p.begin(),p.end());
    }
    
    void solve(){
        int n,m;
        cin>>n>>m;
        vector<int> a(n+1),p(m),ao,ae;
        int sum=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            sum+=a[i];
            if(i&1) ao.push_back(a[i]);
            else ae.push_back(a[i]);
        }
    
        fun(ao);
        fun(ae);
    
        int cnto=0,cnte=0;
        for(int i=0;i<m;i++){
            cin>>p[i];
            if(p[i]&1) cnto++;
            else cnte++;
        }
        //cout<<cnto<<" "<<cnte<<endl;
    
        int ans=0;
        for(int i=0;i<ao.size()&&i<cnto;i++){
            //cout<<ao[i]<<endl;
            if(i&&ao[i]<=0) break;
            ans+=ao[i];
        }
        for(int i=0;i<ae.size()&&i<cnte;i++){
            //cout<<ae[i]<<endl;
            if(i&&ae[i]<=0) break;
            ans+=ae[i];
        }
    
        cout<<sum-ans<<endl;
    
        return ;
    }
    
    
    signed main(){
        int t;
        cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }