链接: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; }