#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N = 2e5 + 500;
int len, num[N], block[N], gt[N], L[N], R[N]; long long ans = 0;
long long work(int x, int k) { int l = L[k], r = R[k], res = R[k] + 1; while (l <= r) { int mid = (l + r) >> 1; if (block[mid] > x) res = mid, r = mid - 1; else l = mid + 1; } return R[k] - res + 1; }
void update(int l, int r) { if (gt[l] == gt[r])//直接暴力枚举 { for (int i = l + 1; i < r; i++) { if (num[r] > num[i]) ans++; else if (num[r] < num[i]) ans--; if (num[l] < num[i]) ans++; else if (num[l] > num[i]) ans--; } if (num[l] > num[r]) ans--; else if (num[l] < num[r]) ans++; swap(num[l], num[r]); } else { int i = l, j = r; i++, j--; while (gt[i] == gt[l]) { if (num[r] > num[i]) ans++; else if (num[r] < num[i]) ans--; if (num[l] < num[i]) ans++; else if (num[l] > num[i]) ans--; i++; } while (gt[j] == gt[r]) { if (num[r] > num[j]) ans++; else if (num[r] < num[j]) ans--; if (num[l] < num[j]) ans++; else if (num[l] > num[j]) ans--; j--; } for (int k = gt[i]; k <= gt[j]; k++) { ans += work(num[l], k); ans -= len - work(num[l], k); ans += len - work(num[r], k); ans -= work(num[r], k); }//二分找个数 if (num[l] > num[r]) ans--; else if (num[l] < num[r]) ans++; swap(num[l], num[r]); for (int k = L[gt[r]]; k <= R[gt[r]]; k++) block[k] = num[k]; for (int k = L[gt[l]]; k <= R[gt[l]]; k++) block[k] = num[k]; sort(block + L[gt[l]], block + R[gt[l]] + 1); sort(block + L[gt[r]], block + R[gt[r]] + 1);//更行块中的数值 } }
int main() { int n, k; scanf("%d%d", &n, &k); len = sqrt(n); for (int i = 1; i <= n; i++) gt[i] = (i - 1) / len + 1, block[i] = i, num[i] = i; for (int i = 1; i <= gt[n]; i++) { L[i] = (i - 1) * len + 1, R[i] = i * len; sort(block + L[i], block + R[i] + 1); }//预处理区间端点 while (k--) { int l, r; scanf("%d%d", &l, &r); if (l > r) swap(l, r); update(l, r);//进行更新 printf("%lld\n", ans); } return 0; }