链接:https://vjudge.net/contest/400607#problem/I
思路:思路还是很简单的,要么把所有的防卫都打掉,要么留下所有的防卫。剩下就是些细节问题啦
代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5+7;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
bool cmp(int x, int y){
    return x > y;
}
struct Node{
    int x, g;
    bool operator < (const Node n1) {
        return x < n1.x;
    }
}b[maxn];
set<int> st1;
map<int, int> mp1;
int a[maxn];

vector<int> df, udf;
signed main()
{
    int t, cnt = 0;
    scanf("%d",&t);
    while(t--)
    {
        int n = read(), m = read();
        mp1.clear(); df.clear(); udf.clear(); st1.clear(); 
        for(int i = 0; i < n; i++) {
            a[i] = read();
            if(!mp1[a[i]]) st1.insert(a[i]);
            mp1[a[i]]++;
        }
        sort(a, a+n, cmp);
        for(int i = 1; i <= m; i++) {
            b[i].x = read();
        }
        for(int i = 1; i <= m; i++) {
            b[i].g = read();
        }
        int ans1 = 0, ans2 = 0;    //ans1是守卫全死,ans2是守卫全活 
        sort(b+1, b+m+1);
        for(int i = m; i >= 1; i--) {
            if(b[i].g == 0) udf.push_back(b[i].x);
            else df.push_back(b[i].x);            
        }

        int sz;
        //op1
        bool flag = 1;
        sz = df.size();
        for(int i = 0; i < sz; i++) {
            auto it = st1.lower_bound(df[i]);
            if(it == st1.end()) {
                flag = 0;//守卫全死这种情况不存在 
                ans1 = 0;
                break;
            }
            mp1[*it]--;
            if(mp1[*it] == 0) {
                st1.erase(*it);
            }
        }
        if(flag)
        {
            bool flag1 = 1;
            sz = udf.size();
            for(int i = 0; i < sz; i++) {
                auto it = st1.lower_bound(udf[i]);
                if(it == st1.end()) {
                    flag1 = 0;
                    break;    //剩余的都不能造成伤害 
                }
                mp1[*it]--;
                ans1 += *it-udf[i];
                if(mp1[*it] == 0) {
                    st1.erase(*it);
                }
            }
            if(!st1.empty() && flag1)
            {
                for(auto it : st1) {
                    ans1 += mp1[it]*it;
                }
            }
        }


        //op2
        sz = udf.size();
        sort(udf.begin(), udf.end());
        for(int i = 0; i < sz && i < n; i++) {
            if(a[i] >= udf[i]) {
                ans2 += a[i]-udf[i];
            }
            else break;
        }
        printf("Case %d: %d\n",++cnt, max(ans1, ans2));
    }

    return 0;
}