卡片
2024年12月24日大约 2 分钟
50 分
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
int n, k;
int a[MAXN + 5], b[MAXN + 5];
int q, m, temp;
vector<int> all;
bool vis[MAXN + 5]; // 被标记了不能翻转?
long long sum;
int id[MAXN + 5];
bool cmp(int x, int y)
{
return a[x] > a[y];
}
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
sum = 0;
for (int i = 1; i <= n; i++)
{
sum += a[i];
a[i] = b[i] - a[i]; // 转换成反转后的增益
id[i] = i;
}
sort(id + 1, id + n + 1, cmp);
cin >> q;
while (q--)
{
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> temp;
all.push_back(temp);
vis[temp] = true;
}
long long now = 0;
for (int i = 1, j = 0; i <= n && j < k; i++)
{
// 被标记了的不能翻转
if (vis[id[i]])
continue;
j++;
now += a[id[i]];
}
cout << sum + now << "\n";
for (int i = 0; i <= m - 1; i++)
vis[all[i]] = false;
all.clear();
}
return 0;
}
100 分
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 100000;
int n, k;
int a[MAXN + 5], b[MAXN + 5];
int q, m, temp;
vector<int> all;
long long sum;
int id[MAXN + 5]; // 按反转后权值从大到小排序后的 id
int rnk[MAXN + 5]; // 每个 id 排序后的排名
long long ans[MAXN + 5]; // a[id[1]]~a[id[i]] 之和
bool cmp(int x, int y)
{
return a[x] > a[y];
}
bool cmpp(int x, int y)
{
return rnk[x] < rnk[y];
}
signed main()
{
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
sum = 0;
for (int i = 1; i <= n; i++)
{
sum += a[i];
a[i] = b[i] - a[i]; // 转换成反转后的增益
id[i] = i;
}
sort(id + 1, id + n + 1, cmp);
for (int i = 1; i <= n; i++)
{
rnk[id[i]] = i;
ans[i] = ans[i - 1] + a[id[i]];
}
cin >> q;
while (q--)
{
cin >> m;
all.clear();
for (int i = 1; i <= m; i++)
{
cin >> temp;
all.push_back(temp);
}
sort(all.begin(), all.end(), cmpp);
int now = k; // 需要对 1~now 进行翻转
long long sumNow = 0; // 所有其中不能翻转的贡献之和
for (int i = 0; i < m; i++)
{
temp = all[i];
if (rnk[temp] <= now)
{
sumNow += a[temp];
now++;
}
}
cout << sum + ans[now] - sumNow << "\n";
}
return 0;
}