。。。一开始傻傻暴力的。。
后来才知道是树状数组求逆序数。。
还是先看清楚数据量啊!
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<iomanip> #include<climits> #include<string.h> #include<cmath> #include<stdlib.h> #include<vector> #include<stack> #include<set> using namespace std; #define INF 1000000007 #define MAXN 4010 #define Mod 1000007 #define N 100010 #define NN 30 #define sigma_size 3 const int MAX = 1000100; const int maxn = 6e5 + 10; using namespace std; typedef long long LL; LL total[N], ans; int num[N], C[MAX], S[MAX], b[N]; int lowbit(int x) { return x&(-x); } void add(int pos,int num,int *p) { while (pos <= MAX) { p[pos] += num; pos += lowbit(pos); } } int sum(int end, int *p) { int cnt = 0; while (end > 0) { cnt += p[end]; end -= lowbit(end); } return cnt; } void init() { total[0] = 0; for (int i = 1; i < N; ++i) { total[i] = total[i - 1] + i; } } int main() { int t; init(); while (cin >> t){ for (int j = 0; j < t; ++j){//因为第一个数前面比它小的数没有,所以j要从0开始 cin >> num[j]; add(num[j] + 1, 1, C); b[j] = j - sum(num[j], C);;//Sum(num[j],C)求的就是小于num[j]的个数,j - Sum(num[j],C)就是前j个数中大于num[j]的个数 b[j] -= sum(num[j] + 1, C) - sum(num[j], C) - 1;//不包括本身这个数 } ans = 0; for (int j = t - 1; j > -1; --j) {//反过来求第j个数右边中小于它的数的个数 add(num[j] + 1, 1, S); b[j] += sum(num[j], S);//sum(num[j],S)求的就是小于num[j]的个数 ans += total[b[j]]; } cout << ans << endl; } return 0; }