[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;
}

 

posted @ 2018-04-06 15:52  xayata  阅读(165)  评论(0编辑  收藏  举报