For xl, xl + 1 ...... Xr, which minimizes [xi-x] and obviously x should be the median. The median value can be solved by finding K-digit numbers, and the tree can be divided.
For summation, there are two parts: the part smaller than x, the part greater than y, and the sum of the values saved to the left subtree when building the tree.
The final sum is ave * (lnum-rnum) + rsum-lsum
Ave is the median, lnum is the number of left sub-numbers, that is, the number smaller than the median, rnum is the right sub-number, lsum indicates the sum smaller than the median
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <algorithm>
# Define N 100005
# Define LL _ int64
Using namespace std;
Struct Node {
Int left, right, mid;
} Tree [N * 4];
Int sa [N], num [20] [N], cnt [20] [N]; // sa is sorted. num records the sorting result of each layer, cnt [deep] [I] indicates the depth layer. How many of the first I numbers enter the left subtree?
LL Lsum [20] [N], sum [N];
Int n, q;
Void debug (int d ){
For (int I = 1; I <= n; I ++)
Printf ("% d", num [d] [I]);
Printf ("\ n ");
}
Void bulid (int step, int l, int r, int deep ){
Tree [step]. left = l;
Tree [step]. right = r;
Tree [step]. mid = (l + r)> 1;
If (l = r)
Return;
Int mid = (l + r)> 1;
Int mid_val = sa [mid], lsum = mid-l + 1 ;;
For (int I = l; I <= r; I ++)
If (num [deep] [I] <mid_val)
Lsum --; // lsum indicates how many values are required in the left subtree
Int L = l, R = mid + 1;
Lsum [deep] [0] = 0;
For (int I = l; I <= r; I ++ ){
If (I = l)
Cnt [deep] [I] = 0;
Else
Cnt [deep] [I] = cnt [deep] [I-1];
Lsum [deep] [I] = Lsum [deep] [I-1];
If (num [deep] [I] <mid_val | (num [deep] [I] = mid_val & lsum> 0) {// left subtree
Num [deep + 1] [L ++] = num [deep] [I];
Cnt [deep] [I] ++;
Lsum [deep] [I] + = (LL) num [deep] [I];
If (num [deep] [I] = mid_val)
Lsum --;
}
Else
Num [deep + 1] [R ++] = num [deep] [I];
}
// Debug (deep );
Bulid (2 * step, l, mid, deep + 1 );
Bulid (2 * step + 1, mid + 1, r, deep + 1 );
}
Int lnum;
LL lsum;
Int query (int step, int l, int r, int k, int deep ){
If (l = r)
Return num [deep] [l];
Int s1, s2; // s1 indicates the number of left subtree in [tree [step]. left L-1 ].
If (tree [step]. left = l)
S1 = 0;
Else
S1 = cnt [deep] L-1];
S2 = cnt [deep] [r]-s1; // s2 is the number of left subtree in [l, r]
If (k <= s2) // The number of left subtree is greater than k, recursive left subtree
Return query (2 * step, tree [step]. left + s1, tree [step]. left + s1 + s2-1, k, deep + 1 );
Int b1 = l-1-tree [step]. left + 1-s1; // b1 is the number of right subtree in [tree [step]. left L-1]
Int b2 = r-l + 1-s2; // b2 indicates the number of right subtree in [l, r ].
Lnum + = s2;
Lsum = (LL) lsum + Lsum [deep] [r]-Lsum [deep] L-1];
Return query (2 * step + 1, tree [step]. mid + 1 + b1, tree [step]. mid + 1 + b1 + b2-1, k-s2, deep + 1 );
}
Int main (){
Int cas = 0;
Int t;
Scanf ("% d", & t );
While (t --){
Scanf ("% d", & n );
Sum [0] = 0;
For (int I = 1; I <= n; I ++ ){
Scanf ("% d", & num [1] [I]);
Sa [I] = num [1] [I];
Sum [I] = (LL) sum [I-1] + sa [I];
}
Sort (sa + 1, sa + n + 1 );
Bulid (1, 1, n, 1 );
Scanf ("% d", & q );
Printf ("Case # % d: \ n", ++ cas );
While (q --){
Int l, r, k;
Scanf ("% d", & l, & r );
L ++; r ++;
K = (r-l + 2)> 1;
Lnum = 0;
Lsum = 0; www.2cto.com
Int ave = query (1, l, r, k, 1 );
Printf ("% I64d \ n", (LL) ave * (lnum-(r-l + 1-lnum )) + sum [r]-sum L-1]-lsum );
}
Puts ("");
}
Return 0;
}
By ACM_cxlove