首先归并求出逆序对个数,如果奇数记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;
}