本题求逆序对的思路还是按照归并排序的过程去求解,但不同之处在于本题需要不断的变换区间里面数的排列。首先考虑在每一次变换之后都去求解逆序对的数量肯定是会超时的。
然后可以联想到如果在区间发生变化之后快速求出逆序对的个数,即可发现在一个区间里面翻转之后逆序对的个数=区间里面的对数-翻转之前逆序对的个数。
可以列出公式:ans-(r-l+1)*(r-l)/2-2x(ans是逆序对的总个数,x是反转之前区间里面逆序对的个数)。可知2x必然是偶数,那么ans奇偶性的变化就取决于(r-l+1)*(r-l)/2,
解到这里就可以发现每一个奇偶性的变化仅仅取决于(r-l+1)*(r-l)/2的奇偶性。这样就可以不必要从新去求逆序对的个数。
#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

const int maxn = 1e5+10;
int a[maxn];
int temp[maxn];
ll cnt = 0;

int read() {
    int num = 0, k = 1;
    char c = getchar();
    while (!(c=='-'||(c>='0'&&c<='9'))) {
        c = getchar();
    }
    while (c=='-') {
        k = -k;
        c = getchar();
    }
    while (c>='0'&&c<='9') {
        num = num*10 + (c-'0');
        c = getchar();
    }
    return num*k;
}

void Merge(int l1, int r1, int l2, int r2) 
{
    memset(temp, 0, sizeof(temp));
    int n = 0, begin = l1;
    while (l1<=r1&&l2<=r2) {
        if (a[l1]<=a[l2]) temp[n++] = a[l1++];
        else {
            temp[n++] = a[l2++];
            cnt += r1-l1+1;
        }
    }
    while (l1<=r1) temp[n++] = a[l1++];
    while (l2<=r2) temp[n++] = a[l2++];
    for (int i=0;i<n;i++) {
        a[begin+i] = temp[i];
    }
}

void find_inv_num(int l, int r) 
{
    if (l==r) return ;
    int mid = (l+r)/2;
    find_inv_num(l, mid);
    find_inv_num(mid+1, r);
    Merge(l, mid, mid+1, r);
}

int main() {
    int n;
    scanf("%d", &n);
    for (int i=1;i<=n;i++) {
        a[i] = read();
    }
    find_inv_num(1, n);
    int p;
    if (cnt%2==0) p = 1;
    else p = 0;
    int m;
    int l, r;
    scanf("%d", &m);
    while (m--) {
        l = read();r=read();
        int jio = (r-l+1)*(r-l)/2;
        if (jio&1==1) {
            p = p^1;
        }
        if (p) {
            printf("like\n");
        } else {
            printf("dislike\n");
        }
    }
    
    return 0;
}