视频加载失败

安吉D17 T3

2975 字
15 分钟
安吉D17 T3
原题呈现

P12459 亲密的厨师 / Intimate Chef#

题目描述#

在某家玻利维亚餐厅,有 NN 位厨师,编号从 11NN.厨师 ii (1iN1 \le i \le N) 可以制作美味度为 AiA_i 的锡尔潘乔 (silpancho) 和美味度为 BiB_i 的皮克马乔 (pique macho).

然而,这些厨师都有很强的个性,因此有 MM 对厨师彼此不和.第 jj 对 (1jM1 \le j \le M) 不和的厨师是厨师 UjU_j 和厨师 VjV_j

来到这家餐厅的顾客会按以下方式用餐:

  • 选择满足 1p<qN1 \le p < q \le N 的整数 p,qp, q,并委托厨师 pp 和厨师 qq 这两人制作料理.但是,不能委托不和的两人组制作料理.
  • 锡尔潘乔和皮克马乔这两道菜都由厨师 pp 和厨师 qq 中能够做出更高美味度料理的那位厨师制作.如果对于某道菜,两人都能做出相同美味度的料理,则由其中一人制作.注意,一位厨师可以制作两道菜.
  • 顾客的满意度是锡尔潘乔的美味度和皮克马乔的美味度之和.

这家餐厅来了 QQ 位顾客,编号从 11QQ

顾客 kk (1kQ1 \le k \le Q) 会委托在所有可以委托的两人组中,满意度第 XkX_k 高的两人组制作料理.具体来说,如果满意度为 SS,则选择使得 S×N2+p×N+qS \times N^2 + p \times N + q 的值是第 XkX_k 高的厨师 pp 和厨师 qq (1p<qN1 \le p < q \le N) 两人组来制作料理.

给定餐厅厨师和顾客的信息,请编写一个程序来计算顾客 kk (1kQ1 \le k \le Q) 的满意度.

输入格式#

输入按照如下格式给出:

N M QA1 A2  ANB1 B2  BNU1 V1U2 V2UM VMX1 X2  XQ\begin{aligned} &N\ M\ Q\\ &A_1\ A_2\ \ldots\ A_N\\ &B_1\ B_2\ \ldots\ B_N\\ &U_1\ V_1\\ &U_2\ V_2\\ &\vdots\\ &U_M\ V_M\\ &X_1\ X_2\ \ldots\ X_Q\\ \end{aligned}

输出格式#

输出 QQ 行.第 kk 行 (1kQ1 \le k \le Q) 输出顾客 kk 的满意度.

输入输出样例 #1#

输入 #1#

4 2 4
2 7 3 5
4 3 4 8
1 3
2 4
1 2 3 4

输出 #1#

13
13
11
11

输入输出样例 #2#

输入 #2#

4 3 1
3 6 5 4
1 1 1 1
1 2
2 3
2 4
1

输出 #2#

6

输入输出样例 #3#

输入 #3#

5 0 4
1 2 3 4 5
5 4 3 2 1
3 9 10 1

输出 #3#

9
7
7
10

输入输出样例 #4#

输入 #4#

13 12 10
2 28 28 60 48 77 63 92 13 71 36 91 87
85 7 64 15 55 92 66 91 83 35 49 22 61
2 9
8 13
7 11
9 11
8 12
5 12
4 7
11 12
10 12
4 11
1 5
3 8
49 21 46 13 20 41 6 33 24 7

输出 #4#

121
169
129
174
169
137
183
148
169
183

说明/提示#

样例 1 解释#

可以委托制作料理的厨师二人组有 4 种,每种组合的顾客满意度如下:

  • 选择厨师 1 和厨师 2 时,锡尔潘乔由厨师 2 制作,皮克马乔由厨师 1 制作.因此,锡尔潘乔的美味度为 7,皮克马乔的美味度为 4.所以,顾客的满意度为 7+4=117 + 4 = 11
  • 选择厨师 1 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 8.所以,顾客的满意度为 5+8=135 + 8 = 13
  • 选择厨师 2 和厨师 3 时,锡尔潘乔由厨师 2 制作,皮克马乔由厨师 3 制作.因此,锡尔潘乔的美味度为 7,皮克马乔的美味度为 4.所以,顾客的满意度为 7+4=117 + 4 = 11
  • 选择厨师 3 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 8.所以,顾客的满意度为 5+8=135 + 8 = 13

因此,对于每位顾客,可以得到以下信息:

  • 顾客 1 选择厨师 3 和厨师 4 的二人组.因此,顾客 1 的满意度为 13.
  • 顾客 2 选择厨师 1 和厨师 4 的二人组.因此,顾客 2 的满意度为 13.
  • 顾客 3 选择厨师 2 和厨师 3 的二人组.因此,顾客 3 的满意度为 11.
  • 顾客 4 选择厨师 1 和厨师 2 的二人组.因此,顾客 4 的满意度为 11.

这个输入样例满足子任务 1, 7, 8 的约束.

样例 2 解释#

可以委托制作料理的厨师二人组有 3 种,每种组合的顾客满意度如下:

  • 选择厨师 1 和厨师 3 时,锡尔潘乔由厨师 3 制作,皮克马乔由厨师 1 或厨师 3 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 1.所以,顾客的满意度为 5+1=65 + 1 = 6
  • 选择厨师 1 和厨师 4 时,锡尔潘乔由厨师 4 制作,皮克马乔由厨师 1 或厨师 4 制作.因此,锡尔潘乔的美味度为 4,皮克马乔的美味度为 1.所以,顾客的满意度为 4+1=54 + 1 = 5
  • 选择厨师 3 和厨师 4 时,锡尔潘乔由厨师 3 制作,皮克马乔由厨师 3 或厨师 4 制作.因此,锡尔潘乔的美味度为 5,皮克马乔的美味度为 1.所以,顾客的满意度为 5+1=65 + 1 = 6

因此,对于顾客 1,可以得到以下信息:

  • 顾客 1 选择厨师 3 和厨师 4 的二人组.因此,顾客 1 的满意度为 6.

这个输入样例满足子任务 1, 3, 4, 5, 6, 7, 8 的约束.

数据范围#

  • 2N4×1052 \le N \le 4\times 10^5
  • 1Ai1091 \le A_i \le 10^9 (1iN1 \le i \le N)
  • 1Bi1091 \le B_i \le 10^9 (1iN1 \le i \le N)
  • 0M4×1050 \le M \le 4\times 10^5
  • M<N(N1)÷2M < N(N - 1) \div 2
  • 1Uj<VjN1 \le U_j < V_j \le N (1jM1 \le j \le M)
  • (Ui,Vi)(Uj,Vj)(U_i, V_i) \neq (U_j, V_j) (1i<jM1 \le i < j \le M)
  • 1Q4×1051 \le Q \le 4\times 10^5
  • 1Xk4×1051 \le X_k \le 4\times 10^5 (1kQ1 \le k \le Q)
  • XkN(N1)÷2MX_k \le N(N - 1) \div 2 - M (1kQ1 \le k \le Q)
  • 输入的所有值都是整数.

子任务#

  1. (4 分) N50N \le 50, M50M \le 50, Q50Q \le 50, Xk50X_k \le 50 (1kQ1 \le k \le Q).
  2. (9 分) Bi=1B_i = 1 (1iN1 \le i \le N), M=0M = 0, Q=1Q = 1.
  3. (10 分) Bi=1B_i = 1 (1iN1 \le i \le N), Q=1Q = 1.
  4. (5 分) Bi=1B_i = 1 (1iN1 \le i \le N).
  5. (29 分) N105N \le 10^5, M105M \le 10^5, Q=1Q = 1, X1=1X_1 = 1.
  6. (14 分) N105N \le 10^5, M105M \le 10^5, Q=1Q = 1, X1105X_1 \le 10^5.
  7. (18 分) N105N \le 10^5, M105M \le 10^5, Q105Q \le 10^5, Xk105X_k \le 10^5 (1kQ1 \le k \le Q).
  8. (11 分) 没有额外的限制.
小技巧

观察本题排序条件 S×N2+p×N+qS \times N^2 + p \times N + q,因为系数为 N2N^2NN,所以该问题可以看作以 SS 为第一关键字,pp 为第二关键字,qq 为第三关键字进行排序.

一般的,看到 a×n2+b×n+ca\times n^2 + b\times n + c 进行排序,可以将其拆分为关键字排序.

我们想来想想,如果没有不和的厨师,问题应该怎么做.

观察此题,由于我们要求第 kk 大,先来思考 k=1k=1 选择.因此需要将 aa 数组和 bb 数组从大到小排序,这样,同时选择 a1a_1b1b_1 就可以了.那第二大呢?显然,第二大可能是 a1a_1b2b_2,也可能是 a2a_2b1b_1.是这两者和的较大值.那第三大呢?不难发现,第三大肯定基于已被扩展过的菜品对,且选择只比其在其中一道菜上后退了一档.

举个例子,若存在三个厨师,其 a,b={1,4},{2,3},{5,5}a,b=\{1,4\},\{2,3\}, \{5,5\}.则首先进行排序:a={5,2,1}a=\{5, 2, 1\}b={5,4,3}b=\{5, 4, 3\}.则首先,第一大的肯定是 {a,b}={5,5}\{a,b\}=\{5, 5\},这是出自同一个人的两个菜品,在这里暂不处理,后文中会把这种情况删去.之后,第二大可能是 {a,b}={5,4}\{a,b\}=\{5, 4\}{a,b}={2,5}\{a,b\}=\{2, 5\}{5,4}\{5, 4\} 对应的厨师对是 {3,1}\{3, 1\},即 5 对应的厨师是 3,4 对应的厨师是 1,厨师对 {1,3}\{1, 3\} 能够带来 10 的满意度.而 {2,5}\{2, 5\} 对应的厨师对是 {2,3}\{2, 3\},也能够带来 10 的满意度.由于满意度相同时按较小厨师编号从小到大排序,则第二大的厨师对是 {1,3}\{1,3\}.此时第三大的菜品对可能是还没用上的 {2,5}\{2, 5\},或者是从 {5,4}\{5, 4\} 扩展出来的 {2,4}\{2, 4\}{5,3}\{5, 3\}.就这样运行下去.

可以使用 bfs 处理.在程序中,以 a1,b1a_1,b_1 为原点扩展,加入优先队列(注意区分菜品二元组和厨师二元组),每一次扩展都尝试找出下一个较大的厨师二元组:取出当前优先队列中能使顾客满意度最高的菜品二元组 ai,bia_i, b_i(这里一个菜品二元组的满意度定义为:两道菜对应的厨师二元组的满意度).其中,若设 aia_i 出自厨师 xxbib_i 出自厨师 yy,则厨师组合 (x,y)(x,y) 就是当前为记录的最大的厨师二元组.将 (x,y)(x,y) 记录之后,将可能的下一个菜品二元组加入优先队列,即 ai+1,bia_{i+1},b_iai,bi+1a_i, b_{i+1}.注意,在二元组加入优先队列时需要去重,避免重复.

当然除此之外,还有一些菜品二元组需要被避免.设菜品二元组 (i,j)(i,j) 对应的厨师二元组 (x,y)(x,y),以下的情况仍旧需要加入优先队列继续用于扩展,但是不能被记录为答案:

  • x=yx=y,显然自己不能和自己合作.
  • 之前已经记录过 (x,y)(x,y)(y,x)(y,x),题目明确说明了 (x,y)(x,y)(y,x)(y,x) 是相同的.
  • 存在一对不和的厨师 u,vu,v,满足 u=x,v=yu=x,v=yu=y,v=xu=y,v=x

在记录了足够多的厨师二元对之后,停止 bfs,由于 k4×105k\leq 4\times 10^5,所以在记录了 kk 对之后就可以停下来.之后对于每一个询问,查询记录 O(1)O(1) 回答即可.

你可能会疑问:那一名厨师 iiaabb 都特别高,这种情况在哪里统计呢?这种情况会在优先队列首的菜品二元组中有且仅有一个是厨师 ii 的时候被统计.显然,这样的菜品二元组有多个,若另一道菜出自厨师 jj,就对应着这名厨师和不同的其他厨师 jj 合作.

标程

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> pii;
const int N = 4e5 + 100;
int n, m, q;
int ans[N], cnt;
int qs[N];
int c[N], d[N];
struct Hash {
size_t operator()(const pii &p) const {
return p.first * (n + 1) + p.second;
}
};
unordered_set<pii, Hash> vis, err;
struct Node {
int v, id;
friend bool operator<(const Node a, const Node b) {
if (a.v == b.v)
return a.id > b.id;
return a.v > b.v;
}
} a[N], b[N];
struct Chefs : public pii {
Chefs(int x, int y) : pii(x, y) {}
int value() const {
int ida = a[first].id;
int idb = b[second].id;
return max(c[ida], c[idb]) + max(d[ida], d[idb]);
}
friend bool operator<(const Chefs &x, const Chefs &y) {
auto sx = x.value();
auto sy = y.value();
if (sx != sy)
return sx < sy;
if (a[x.first].id != a[y.first].id)
return a[x.first].id < a[y.first].id;
return b[x.second].id < b[y.second].id;
}
};
priority_queue<Chefs> pq;
void solve(int need) {
pq.push({1, 1});
while (!pq.empty()) {
auto top = pq.top();
pq.pop();
int chefa = a[top.first].id, chefb = b[top.second].id;
if (vis.find(top) != vis.end()) {
continue;
}
vis.insert(top);
if (err.find({chefa, chefb}) == err.end() && chefa != chefb) {
ans[++cnt] = top.value();
if (cnt >= need)
return;
}
err.insert({chefb, chefa});
Chefs nxt = {top.first + 1, top.second};
if (top.first + 1 <= n && vis.find(nxt) == vis.end()) {
pq.push(nxt);
}
nxt = {top.first, top.second + 1};
if (top.second + 1 <= n && vis.find(nxt) == vis.end()) {
pq.push(nxt);
}
}
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> q;
for (int i = 1; i <= n; i++) {
cin >> a[i].v;
a[i].id = i;
c[i] = a[i].v;
}
for (int i = 1; i <= n; i++) {
cin >> b[i].v;
b[i].id = i;
d[i] = b[i].v;
}
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
if (u > v)
swap(u, v);
err.insert({u, v});
err.insert({v, u});
}
int need = 0;
for (int i = 1; i <= q; i++) {
cin >> qs[i];
need = max(need, qs[i]);
}
solve(min(need, N - 1));
for (int i = 1; i <= q; i++) {
cout << ans[qs[i]] << endl;
}
return 0;
}

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

安吉D17 T3
https://blog.jerrylab.top/posts/problem/anji2026/D17/T3/
作者
Jerry
发布于
2026-08-19
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Jerry
Hello, I'm Jerry.
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
最新动态
站点统计
文章
80
分类
3
标签
35
总字数
89,198
运行时长
0
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.16.5
文章许可
CC BY-NC-SA 4.0