牛客IOI周赛26-提高组 A.逆序对(逆序对思维)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客IOI周赛26-提高组 A.逆序对(逆序对思维)相关的知识,希望对你有一定的参考价值。
考虑一次操作对逆序数的影响
对于操作一交换 a l a_l al和 a r a_r ar
设 l e n = r − l − 1 len=r-l-1 len=r−l−1
先考虑 a l a_l al和 a r a_r ar形成的逆序对数为 k k k,那么交换后数量为 1 − k 1-k 1−k
考虑 a l a_l al和 a [ l + 1... r − 1 ] a[l+1...r-1] a[l+1...r−1]形成 z z z个逆序对,那么交换之后就形成 l e n − z len-z len−z个逆序对
考虑 a r a_r ar和 a [ l + 1... r − 1 ] a[l+1...r-1] a[l+1...r−1]形成 r r r个逆序对,那么交换之后就形成 l e n − r len-r len−r个逆序对
也就是开始逆序对数为 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+(1−k)
显然交换先后的奇偶性一定不同。
再考虑操作二翻转整个区间 [ l , r ] [l,r] [l,r]
设 l e n = r − l + 1 len=r-l+1 len=r−l+1,且翻转前区间逆序对为 x x x
那么反转后区间逆序对为 l e n ∗ ( l e n − 1 ) / 2 − x len*(len-1)/2-x len∗(len−1)/2−x
考虑当 l e n ∗ ( l e n − 1 ) / 2 len*(len-1)/2 len∗(len−1)/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.逆序对(逆序对思维)的主要内容,如果未能解决你的问题,请参考以下文章