强制在线的区间询问逆序对数
如果不是强制在线
就是可以用莫队乱搞啦
强制在线的话
用f[i][j]记录第i块到第j个点之间的逆序对数
用s[i][j]记录前i块中小于等于j的数字个数
离散化一下
BIT用来处理需要暴力的地方即可
下面是代码
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstring> 5 using namespace std; 6 #define isdigit(x) (x <= ‘9‘ && x >= ‘0‘) 7 #define lowbit(x) (x & (-x)) 8 const int N = 5e4 + 5; 9 const int M = 300; 10 11 struct s { 12 int u, v; 13 inline bool operator < (const s &o) const { 14 return u < o.u; 15 } 16 } a[N]; 17 18 inline void read(int &ans) { 19 ans = 0; 20 static char buf = getchar(); 21 for (; !isdigit(buf); buf = getchar()); 22 for (; isdigit(buf); buf = getchar()) 23 ans = ans * 10 + buf - ‘0‘; 24 } 25 26 int n, cnt, maxn, sz; 27 int s[M][N], f[M][N], c[N], d[N], b[N]; 28 29 inline void add(int x, int a) { 30 while (x <= maxn) { 31 c[x] += a; 32 x += lowbit(x); 33 } 34 } 35 36 inline int query(int x) { 37 int ans = 0; 38 while (x > 0) { 39 ans += c[x]; 40 x -= lowbit(x); 41 } 42 return ans; 43 } 44 45 inline void work(int x) { 46 int h = (x - 1) * sz + 1; 47 int t = x * sz; 48 for (int i = h; i <= n; i++) 49 add(d[i], 1), f[x][i] = f[x][i - 1] + i - h + 1 - query(d[i]); 50 memset(c, 0, sizeof(c)); 51 for (int i = h; i <= t; i++) s[x][d[i]]++; 52 for (int i = 1; i <= maxn; i++) s[x][i] += s[x][i - 1]; 53 for (int i = 1; i <= maxn; i++) s[x][i] += s[x - 1][i]; 54 } 55 56 int main() { 57 read(n); 58 sz = sqrt(n); 59 for (int i = 1; i <= n; i++) { 60 read(a[i].u); a[i].v = i; 61 b[i] = (i - 1) / sz + 1; 62 } 63 cnt = b[n]; 64 sort(a + 1, a + n + 1); 65 int last = 1; d[a[1].v] = 1; 66 for (int i = 2; i <= n; i++) { 67 if (a[i].u == a[i - 1].u) d[a[i].v] = last; 68 else d[a[i].v] = ++last; 69 } 70 maxn = last; 71 for (int i = 1; i <= cnt; i++) 72 work(i); 73 int m; read(m); 74 int ans = 0; 75 while (m--) { 76 int l, r; 77 read(l); read(r); 78 l = l ^ ans; r = r ^ ans; 79 ans = 0; 80 if (l > r) swap(l, r); 81 if (b[l] == b[r]) { 82 for (int i = l; i <= r; i++) 83 add(d[i], 1), ans += i - l + 1 - query(d[i]); 84 for (int i = l; i <= r; i++) add(d[i], -1); 85 } 86 else { 87 ans = f[b[l] + 1][r]; 88 for (int i = (b[r] - 1) * sz + 1; i <= r; i++) add(d[i], 1); 89 for (int i = b[l] * sz; i >= l; i--) 90 add(d[i], 1), ans += query(d[i] - 1) + s[b[r] - 1][d[i] - 1] - s[b[l]][d[i] - 1]; 91 for (int i = (b[r] - 1) * sz + 1; i <= r; i++) add(d[i], -1); 92 for (int i = l; i <= b[l] * sz; i++) add(d[i], -1); 93 } 94 printf("%d\n", ans); 95 } 96 }
原文地址:https://www.cnblogs.com/cminus/p/8571228.html
时间: 2024-10-26 05:47:09