P9757 [COCI 2022/2023 #3] Dirigent
题目描述
信息学冬令营以一场传统舞蹈结营。一共有 nnn 名学生参与。他们每个人都有分别有一个 1∼n1\sim n1∼n 之间的编号。
一开始,指挥者 Kreso 要求学生们围成一个圈,使得每个学生都与另外两个学生拉着手。
Alenka 想知道是否有可能通过将且仅将一对相邻同学分开手,使得这样形成的同学序列按照编号排序。例如,如果他们的顺序是 3 4 1 2,那么圈可以从 4 1 两个同学间断开;但是如果顺序是 2 1 4 3,那么没有一种合理的方式。
在这一晚,Kreso 准备下达 qqq 条指令。在每条指令中,他会要求两个学生交换位置。在每一次交换之后你需要帮助 Alenka 回答他的问题。
输入格式
第一行包含两个整数 n,qn,qn,q,表示学生的数量和交换数。
第二行包含 nnn 个整数 aia_iai,描述第 iii 个位置的学生编号。
在接下来的 qqq 行中,每行两个整数 xi,yix_i,y_ixi,yi,描述 Kreso 的第 iii 条指令,即标号 xix_ixi 的学生和标号 yiy_iyi 的学生交换位置。
输出格式
共 qqq 行。
在第 iii 行输出在第 iii 次交换后 Alenka 的问题的答案。
如果答案是肯定的,输出 DA,否则输出 NE。
输入输出样例 #1
输入 #1
5 2
2 3 4 5 1
1 3
3 1
输出 #1
NE
DA
输入输出样例 #2
输入 #2
4 2
2 3 1 4
4 2
3 4
输出 #2
NE
DA
输入输出样例 #3
输入 #3
6 5
2 1 5 6 3 4
3 1
3 4
3 2
4 5
5 4
输出 #3
NE
NE
DA
NE
DA
说明/提示
【样例解释 #2】

【数据范围】
| 子任务 | 分值 | 特殊性质 |
|---|---|---|
| 111 | 151515 | n,q≤500n,q \leq 500n,q≤500 |
| 222 | 202020 | n,q≤5000n,q \leq 5000n,q≤5000 |
| 333 | 353535 | 无特殊性质 |
对于 100%100\%100% 的数据,满足 1≤n,q≤3×105,1≤ai≤n,1≤xi,yi≤n,xi≠yi1\leq n,q \leq 3\times10^5,1\le a_i\le n, 1\le x_i,y_i\le n,x_i\neq y_i1≤n,q≤3×105,1≤ai≤n,1≤xi,yi≤n,xi=yi。
本题满分 707070 分。
C++实现
#include <bits/stdc++.h>
using namespace std;
const int N = 300005;
int n, q, a[N], bad;
pair<int, int> stu[N];
int id1[N], id2[N];
bool is_bad(pair<int, int> p) {return p.first > p.second; }
int change(int a, int b, int c, int d) {
return is_bad(stu[a]) + (b != a ? is_bad(stu[b]) : 0)
+ ((c != b && c != a) ? is_bad(stu[c]) : 0)
+ ((d != c && d != b && d != a) ? is_bad(stu[d]) : 0);
}
int main() {
scanf("%d %d", &n, &q);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) {
if(i == n) stu[i] = make_pair(a[n], a[1]), id1[a[n]] = id2[a[1]] = i;
else stu[i] = make_pair(a[i], a[i + 1]), id1[a[i]] = id2[a[i + 1]] = i;
if(is_bad(stu[i])) bad++;
}
while(q--) {
int x, y; scanf("%d %d", &x, &y);
int a = id1[x], b = id2[x], c = id1[y], d = id2[y];
bad -= change(a, b, c, d);
stu[id1[x]].first = stu[id2[x]].second = y;
stu[id1[y]].first = stu[id2[y]].second = x;
id1[x] = c; id2[x] = d; id1[y] = a; id2[y] = b;
bad += change(a, b, c, d);
if(bad == 1) puts("DA");
else puts("NE");
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
347

被折叠的 条评论
为什么被折叠?



