牛客IOI周赛26-提高组 A.逆序对(逆序对思维)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客IOI周赛26-提高组 A.逆序对(逆序对思维)相关的知识,希望对你有一定的参考价值。

LINK


考虑一次操作对逆序数的影响

对于操作一交换 a l a_l al a r a_r ar

l e n = r − l − 1 len=r-l-1 len=rl1

先考虑 a l a_l al a r a_r ar形成的逆序对数为 k k k,那么交换后数量为 1 − k 1-k 1k

考虑 a l a_l al a [ l + 1... r − 1 ] a[l+1...r-1] a[l+1...r1]形成 z z z个逆序对,那么交换之后就形成 l e n − z len-z lenz个逆序对

考虑 a r a_r ar a [ l + 1... r − 1 ] a[l+1...r-1] a[l+1...r1]形成 r r r个逆序对,那么交换之后就形成 l e n − r len-r lenr个逆序对

也就是开始逆序对数为 z + r + k z+r+k z+r+k,交换后为 z + r + 2 l e n + ( 1 − k ) z+r+2len+(1-k) z+r+2len+(1k)

显然交换先后的奇偶性一定不同。

再考虑操作二翻转整个区间 [ l , r ] [l,r] [l,r]

l e n = r − l + 1 len=r-l+1 len=rl+1,且翻转前区间逆序对为 x x x

那么反转后区间逆序对为 l e n ∗ ( l e n − 1 ) / 2 − x len*(len-1)/2-x len(len1)/2x

考虑当 l e n ∗ ( l e n − 1 ) / 2 len*(len-1)/2 len(len1)/2为偶数时翻转前后同奇偶,是奇数不同奇偶…

操作三,操作四同理,很容易就可以得到本次操作是否会改变奇偶性

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int n,m,a[maxn],sum[maxn];
int lowbit(int x){ return x&(-x); }
void add(int x,int val){ for(;x<=n;x+=lowbit(x)) sum[x] += val; }
int ask(int x){ int ans = 0; for( ; x ; x-=lowbit(x)) ans += sum[x]; return ans; }
int main()
{
	scanf("%d%d",&n,&m );
	for(int i=1;i<=n;i++)	scanf("%d",&a[i] );
	int chu = 0;
	for(int i=n;i>=1;i--)
	{
		chu ^= ( 1&ask( a[i] ) );;
		add( a[i],1 );
	}
	int type,l,r,k,len; 
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&type,&l,&r);
		len = r-l+1;
		if( type==1 ) chu ^= 1;//啥也不干 
		else if( type==2 )
		{
			if( 1ll*len*(len-1)/2&1 )	chu ^= 1;
		}
		else
		{
			scanf("%d",&k );
			k %= (r-l+1);
			int yu = r-l+1-k;
			if( (yu&1) && (k&1) )	chu ^= 1;
		}
		if( chu&1 )	puts("1");
		else	puts("0");
	}
	return 0;
}

以上是关于牛客IOI周赛26-提高组 A.逆序对(逆序对思维)的主要内容,如果未能解决你的问题,请参考以下文章

牛客IOI周赛26-普及组 最短路

牛客IOI周赛26-普及组 B. 子序列(int128)

牛客IOI周赛27-提高组 C.马老师(容斥dp)

牛客IOI周赛21-普及组 D.瞎位移群岛(bfs)

牛客IOI周赛27-普及组 D 旅游(简单floyd)

Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对