翻译:
AquaMoon有𝑛个朋友。他们从左到右站成一排,左边的𝑖-th朋友穿着一件写着𝑎𝑖的t恤。每个朋友都有一个方向(左或右)。一开始,每个朋友的方向都是对的。
AquaMoon可以在朋友身上做一些操作。在每次操作中,AquaMoon可以选择两个相邻的朋友并交换他们的位置。每次操作后,选择的两个朋友的方向也会翻转:从左到右,反之亦然。
AquaMoon希望通过一些操作,将写在𝑛朋友t恤上从左往右读的数字变成不递减的。她也希望,所有的朋友最后都会有一个正确的方向。请看看是否可能。
输入
输入由多个测试用例组成。第一行包含单个整数𝑡(1≤𝑡≤50)—测试用例的数量。
每个测试用例的第一行包含一个整数𝑛(1≤𝑛≤105)——Aquamoon的朋友的数量。
第二行包含𝑛整数𝑎1,𝑎2,…,𝑎𝑛(1≤𝑎𝑖≤105)——这些数字写在t恤上。
可以保证所有测试用例的𝑛的总和不超过105。
输出
对于每个测试用例,如果存在一个可能的操作序列,打印“YES”(不带引号);否则,打印“NO”(不带引号)。
您可以打印每个字母在任何情况下(大写或小写)。
例子
inputCopy
3.
4
4 3 2 5
4
3 3 2 2
5
1 2 3 5 4
outputCopy
是的
是的
没有
请注意
第一个测试用例中可能的操作列表:
交换𝑎1和𝑎2。结果序列是3,4,2,5。方向是:左,左,右,右。
交换𝑎2和𝑎3。结果是3 2 4 5。方向是:左,左,右,右。
交换𝑎1和𝑎2。结果序列是2,3,4,5。方向是:对,对,对,对。
大致题意:每次相邻的可以交换位置,每次交换,方向改变。问最后排序,方向是否一致
思路:方向一致,所以每个交换的次数都必须都偶数,每次交换相邻的,所以我们直接记录初始下标,最终下标,判断奇偶。
代码实现:
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long ll;
int n,t;
int a[100005];
int b[100005];
int c[100005][3];
void solv(){
cin>>n;
memset(c,0,sizeof c);
for (int i =1; i<=n; i++) {
cin>>a[i];
b[i]=a[i];
}
sort(a+1, a+1+n);
for (int i =1; i<=n; i++) {
c[a[i]][i&1]++;
c[b[i]][i&1]--;
}
for (int i=1; i<=100000; i++) {
if (c[i][1]||c[i][0]) {
printf("NO\n");return;
}
}
printf("YES\n");
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(); cout.tie();
cin>>t;
while (t--) {
solv();
}
return 0;
}
———————————————————————————————————————————
翻译:
有𝑛个贵族,编号从1到𝑛。贵族𝑖有𝑖的力量。还有𝑚“友谊”。贵族之间的友谊𝑎和𝑏总是相互的。
满足以下两个条件的贵族被定义为易受攻击的:
贵族至少有一个朋友,而且
贵族的朋友都有更高的权力。
您将必须处理以下三种类型的查询。
添加贵族之间的友谊𝑢和𝑣。
移除贵族之间的友谊𝑢和𝑣。
计算以下过程的答案。
整个过程:所有脆弱的贵族同时被杀死,他们所有的友谊也随之终结。这样一来,新贵族就有可能变得脆弱。这个过程不断重复,直到没有贵族受到攻击。可以证明这个过程将在有限时间内结束。在这个过程完成后,你需要计算剩余的贵族数量。
注意,进程的结果不会在查询之间转移,也就是说,每个进程开始时所有的noble都是活的!
输入
第一行是整数𝑛和𝑚(1≤𝑛≤2⋅105,0≤𝑚≤2⋅105)——分别是贵族的数量和原始友谊的数量。
接下来的𝑚行分别包含整数𝑢和𝑣(1≤𝑢,𝑣≤𝑛,𝑢≠𝑣),描述友谊。没有一种友谊被列出两次。
下一行包含整数𝑞(1≤𝑞≤2⋅105)——查询的次数。
接下来的𝑞行包含查询本身,每个查询具有以下三种格式之一。
1𝑢𝑣(1≤𝑢,𝑣≤𝑛,𝑢≠𝑣)——添加一个𝑢和𝑣之间的友谊。可以保证的是,𝑢和𝑣现在不是朋友。
2𝑢𝑣(1≤𝑢,𝑣≤𝑛,𝑢≠𝑣)——删除𝑢和𝑣之间的友谊。可以保证的是,𝑢和𝑣在这一刻是朋友。
3 -打印语句中描述的过程的答案。
输出
对于每个类型3查询,打印一个整数到新行。可以保证至少有一个类型3查询。
例子
inputCopy
4个3
2 1
1 3
3 4
4
3.
1 2 3
1 2 3
3.
outputCopy
2
1
inputCopy
4个3
2 3
3 4
4个1
1
3.
outputCopy
1
请注意
考虑第一个例子。在第一个类型3查询中,我们有下面的图表。
在第一轮过程中,贵族1比他所有的朋友(2和3)都弱,因此被杀死。在第一回合中没有其他贵族是脆弱的。在第二回合,贵族3比他唯一的朋友贵族4弱,因此被杀。在这一点上,这个过程结束了,答案是2。
在第二个类型3查询中,唯一存活的noble是4。
第二个示例只包含一个类型3查询。在第一轮中,两个贵族被杀,在第二轮中,一个贵族被杀。最后的答案是1,因为只有一个贵族能活下来。
题意:就是判断有没有比自己大的,每次小的都会被杀死,问最后存在几个。
思路:刚开始想着,用vector存边模拟,存的话可以直接存,主要是每次删除的复杂度可能有点大,想着用二分找删除后有没有大边,感觉可以写,但感觉太过复杂,后来小企鹅说,可以直接找度,瞬间思路就清晰。因为大的不受小的影响,所以每次记录小的边的度,如果度为0,则存活,后来加边直接用度来判断是否有大边和有几个大边即可。
代码实现:
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
using namespace::std;
typedef long long ll;
ll rs[200005];
int n,m,q,w,e,kl;
int main(){
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
cin>>n>>m;
while (m--) {
cin>>q>>w;
rs[min(q, w)]++;
}
ll an=0;
for (int i =1; i<=n; i++) {
if (!rs[i]) {
an++;
}
}
// for (int i=1; i<=n; i++) {
// printf("%lld ",rs[i]);
// }
// printf("\n");
cin>>q;
while (q--) {
cin>>kl;
if (kl==1) {
cin>>w>>e;
if (!rs[min(e,w)]) {
an--;
// printf("dsad\n");
}
rs[min(e, w)]++;
}
else if(kl==2){
cin>>w>>e;
if (rs[min(e, w)]==1) {
an++;
}
rs[min(e, w)]--;
}
else{
printf("%lld\n",an);
}
}
return 0;
}