Lang:G++
Edit12345678910111213141516171819202122232425262728293031#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;#define N 200100int a[N];int s[40][N];//划分树int num[40][N];//num[i][j] - num[i][j-1] == 1表示第i层第j个数在下层中要被划入左子树void build(int l, int r, int dep = 1){if(l == r){s[dep][l] = s[dep-1][l];return;}int mid = l+r>>1;int cnt = mid-l+1;for(int i = l; i <= r; i++) if(s[dep-1][i] < a[mid]) cnt--;int c1 = l, c2 = mid+1;for(int i = l; i <= r; i++){if(s[dep-1][i] < a[mid] || ( s[dep-1][i] == a[mid] && cnt-- > 0)) s[dep][c1++] = s[dep-1][i];else s[dep][c2++] = s[dep-1][i];num[dep-1][i] = num[dep-1][l-1]+c1-l;}build(l, mid, dep+1);build(mid+1, r, dep+1);}