[Luogu] 火柴排队
https://www.luogu.org/problemnew/show/P1966
离散化
树状数组求逆序对个数
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; const int Mod = 99999997; struct Node { int num, wher; } G_1[N], G_2[N]; int n; int Map1[N], Map2[N], imp[N], work[N]; int Tree[N]; long long Answer; #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } inline bool cmp(Node a, Node b) {return a.num < b.num;} inline int Lowbit(int x) {return x & (-x);} inline int Ask(int x) {int ret = 0; while(x) {ret += Tree[x]; x -= Lowbit(x);} return ret;} void Add(int x) {while(x <= n) {Tree[x] ++; x += Lowbit(x);}} int main () { n = read(); for(int i = 1; i <= n; i ++) G_1[i].num = read(), G_1[i].wher = i; for(int i = 1; i <= n; i ++) G_2[i].num = read(), G_2[i].wher = i; sort(G_2 + 1, G_2 + n + 1, cmp); sort(G_1 + 1, G_1 + n + 1, cmp); for(int i = 1; i <= n; i ++) Map1[G_1[i].wher] = i; for(int i = 1; i <= n; i ++) Map2[G_2[i].wher] = i; for(int i = 1; i <= n; i ++) imp[Map2[i]] = i; for(int i = 1; i <= n; i ++) work[i] = imp[Map1[i]]; for(int i = 1; i <= n; i ++) { int A = Ask(work[i]); Add(work[i]); Answer += (i - 1 - A); while(Answer >= Mod) Answer -= Mod; } cout << Answer; return 0; }