打卡信奥刷题(1887)用C++实现信奥 P9757 [COCI 2022/2023 #3] Dirigent

P9757 [COCI 2022/2023 #3] Dirigent

题目描述

信息学冬令营以一场传统舞蹈结营。一共有 nnn 名学生参与。他们每个人都有分别有一个 1∼n1\sim n1n 之间的编号。

一开始,指挥者 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】

【数据范围】

子任务分值特殊性质
111151515n,q≤500n,q \leq 500n,q500
222202020n,q≤5000n,q \leq 5000n,q5000
333353535无特殊性质

对于 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_i1n,q3×105,1ain,1xi,yin,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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值