[Luogu] 火柴排队

Posted xayata

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;
}

 

以上是关于[Luogu] 火柴排队的主要内容,如果未能解决你的问题,请参考以下文章

[Luogu] 火柴排队

luogu P1966 火柴排队 (逆序对)

Luogu 1966火柴排队

luogu P1966 火柴排队

luogu1966 火柴排队(离散化+树状数组)

luogu 1966 火柴排队 离散化+逆序对