[Cpp]
// HDOJ 3333 Turing Tree line segment Tree single point update segment Query
/*
Question: Sum of numbers with different values in a certain range
Train of Thought: first sort all the queries by the end of the Interval
Then traverse from the beginning of the sequence. When the same element is encountered
Delete the preceding elements to ensure that the elements with duplicates are always closest to the end of the interval.
After conversion, it becomes a simple single-point Update Interval sum.
Discretization is required for large data volumes.
*/
# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
# Define N 30005
# Define M 100005
# Define lson rt <1, l, mid
# Define rson rt <1 | 1, mid + 1, r
Int T, n, m, cnt;
_ Int64 sum [N <2], ans [M];
Int num [N], s [N], vis [N];
Struct node {
Int from;
Int;
Int id;
} Q [M];
Int cmp (const void * a, const void * B ){
Return * (int *) a-* (int *) B;
} Www.2cto.com
Int cmp1 (const void * a, const void * B ){
Return (* (node *) a). to-(* (node *) B).;
}
Void Pushup (int rt ){
Sum [rt] = sum [rt <1] + sum [rt <1 | 1];
}
Void Build (int rt, int l, int r ){
If (l = r ){
Scanf ("% d", & num [cnt]);
S [cnt] = num [cnt];
Sum [rt] = num [cnt ++];
Return;
}
Int mid = (l + r)> 1;
Build (lson );
Build (rson );
Pushup (rt );
}
Void Update (int rt, int l, int r, int x, int c ){
If (l = r ){
Sum [rt] + = c;
Return;
}
Int mid = (l + r)> 1;
If (x <= mid) Update (lson, x, c );
Else Update (rson, x, c );
Pushup (rt );
}
_ Int64 Query (int rt, int l, int r, int L, int R ){
If (L <= l & R> = r)
Return sum [rt];
Int mid = (r + l)> 1;
_ Int64 res = 0;
If (L <= mid) res + = Query (lson, L, R );
If (R> mid) res + = Query (rson, L, R );
Return res;
}
Void Debug (int n ){
Int I;
For (I = 1; I <= n; ++ I)
Printf ("sum [% d] % I64d \ n", I, sum [I]);
}
Int Bin (int key ){
Int l = 0, r = cnt, mid;
While (r> = l ){
Mid = (l + r)> 1;
If (s [mid] = key) return mid;
If (s [mid] <key) l = mid + 1;
Else r = mid-1;
}
Return-1;
}
Void Init (){
Int I;
Cnt = 0;
Scanf ("% d", & n );
Build (1, 1, n );
// Debug (10 );
Qsort (s, n, sizeof (s [0]), cmp );
For (I = cnt = 1; I <n; ++ I)
If (s [I]! = S [I-1])
S [cnt ++] = s [I];
-- Cnt;
Scanf ("% d", & m );
For (I = 0; I <m; ++ I ){
Scanf ("% d", & q [I]. from, & q [I]. );
Q [I]. id = I;
}
Qsort (q, m, sizeof (q [0]), cmp1 );
}
Void Solve (){
Int I, j, cur;
J = 0;
Memset (vis,-1, sizeof (vis ));
For (I = 0; I <n; ++ I ){
Cur = Bin (num [I]);
If (vis [cur] =-1)
Vis [cur] = I + 1;
Else {
Update (1, 1, n, vis [cur],-num [I]);
Vis [cur] = I + 1;
}
For (; j <m; ++ j ){
If (q [j]. to = I + 1 ){
Ans [q [j]. id] = Query (1,1, n, q [j]. from, q [j]. );
}
Else
Break;
}
}
}
Void Print (){
Int I;
For (I = 0; I <m; ++ I)
Printf ("% I64d \ n", ans [I]);
}
Int main (){
Scanf ("% d", & T );
While (T --){
Init ();
Solve ();
Print ();
}
Return 0;
}