列表

详情


NC222132. 逆序对

描述

我们称逆序对为一个序列中满足 的二元组

若一个排列的逆序对个数为奇数,则称它为一个奇排列,否则它被称为偶排列

给出一个长度为 的排列,有 种操作:

对一个长度为 的序列的操作定义如下:

注意上述定义中同一个操作内的移动都是同时进行的。

想要知道每次操作之后这个排列是奇排列还是偶排列。



输入描述

第一行两个整数 ,表示序列的长度和操作的次数。
第二行 个整数,表示一个  至  的排列。
接下来  行,每行三或四个整数,表示一次操作,具体格式及其含义见题目描述。

输出描述

 行表示每次操作后的答案,若为奇排列则输出 ,若为偶排列则输出 

示例1

输入:

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

输出:

1
0
0
1
1

说明:

原排列的逆序对个数为
第一次操作后序列为:,逆序对个数为 ,故输出
第二次操作后序列为:,逆序对个数为 ,故输出
第三次操作后序列为:,逆序对个数为 ,故输出
第四次操作后序列为:,逆序对个数为 ,故输出
第五次操作后序列为:,逆序对个数为 ,故输出

示例2

输入:

10 10
1 4 3 5 2 9 8 6 7 10
1 2 3
2 3 5
4 3 7 2
2 3 5
3 5 7 4
1 2 6
4 1 10 6
3 2 4 3
1 3 4
2 3 9

输出:

0
1
1
0
0
1
1
1
0
1

说明:


原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 217ms, 内存消耗: 2936K, 提交时间: 2021-06-05 20:09:45

#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int n,a[N],m,ans,t[N];
void add(int x){
	for(;x<=n;x+=x&-x)t[x]^=1;
}
int sum(int x){
	int res=0;
	for(;x;x-=x&-x)res^=t[x];
	return res;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=n;i>=1;i--){
		ans^=sum(a[i]);
		add(a[i]);
	}
	while(m--){
		int op,l,r,k;
		scanf("%d%d%d",&op,&l,&r);
		if(op>2)scanf("%d",&k);
		if(op==1)ans^=1;
		else if(op==2)ans^=((r-l+1)/2)&1;
		else if(op>2)ans^=(k*(r-l+1-k))&1;
		cout<<ans<<"\n";
	}
}

上一题