@Acqua
2018-12-08T07:08:26.000000Z
字数 997
阅读 1028
逆序对 数据结构题意:给定长度为的序列s,求数对满足且,。
思路:
1. 求出所有位置的顺序对数量。
2. 维护指针扫描数组,令,则在中小于的数的数量即合法的的数量,这样就确定了第一个顺序对。
3. 反转数组,再次统计顺序对数量,就可以得到在中大于的顺序对数,则
代码:
// La Lune#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define wt(x) (x & -x)using namespace std;typedef long long lune;const lune N = 1e5 + 5;lune n, c[N], seq[N], qes[N], a[N];inline void add(lune pos, lune x){for(lune i = pos; i <= n; i += wt(i))c[i] += x;}inline lune que(lune pos){lune res = 0;for(lune i = pos; i >= 1; i -= wt(i))res += c[i];return res;}int main(){lune T; scanf("%lld", &T);while(T--){memset(seq, 0, sizeof(seq));memset(qes, 0, sizeof(qes));memset(c, 0, sizeof(c));scanf("%lld", &n); lune ans = 0;for(lune i = 1; i <= n; i++){scanf("%lld", &a[i]);seq[i] = que(a[i]);add(a[i], 1);}memset(c, 0, sizeof(c));for(lune i = n; i >= 1; i--){qes[i] = (n - i) - que(a[i]);add(a[i], 1);}lune res = 0;for(lune i = 1; i <= n; i++){ans += res * qes[i];res += seq[i];}printf("%lld\n", ans);}return 0;}