首先归并求出逆序对个数,如果奇数记flag为false,如果偶数记flag为true。
然后循环区间。由于反转区间的逆序对加原区间的逆序对等于该区间的最大逆序对,如果该区间最大逆序对为奇数,那么反转区间与原区间必然有一个的逆序对为奇数,由于反转区间与原区间的逆序对一奇一偶,必然会使总的逆序对由奇变偶或者由偶变奇。
于是改变flag的状态,根据flag的状态输出即可(flag为true输出like,否则输出dislike)
#include<cstdio>
const int maxn = 1e5+1;
int data[maxn];//存放数据
int buf[maxn];//用于归并排序临时存储
int n, k;
bool flag=true;//如果逆序对为0,flag为true
//归并排序求逆序对
void merge(int b,int e)
{
if(b>=e)return ;
int mid=(b+e)>>1;
merge(b,mid);
merge(mid+1,e);
int l=b,r=mid+1, bufi=b;
while(l<=mid&&r<=e){
if(data[r]<=data[l]){
if((mid-l+1)%2)flag=flag^1;
buf[bufi++]=data[r++];
}
else {
buf[bufi++]=data[l++];
}
}
while(l<=mid)buf[bufi++]=data[l++];
while(r<=e)buf[bufi++]=data[r++];
for(int i=b;i<=e;++i)data[i]=buf[i];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&data[i]);
}
merge(1,n);
//printf("Flag:%d\n",flag);
scanf("%d",&k);
int a,b;
for(int i=1;i<=k;++i){
scanf("%d%d",&a,&b);
if((b-a+1)/2%2)flag=flag^1;//如果区间的最大逆序对为奇数
if(flag)printf("like\n");
else printf("dislike\n");
}
return 0;
}

京公网安备 11010502036488号