Question: There are some numbers, which are repeated. Ask the sum of the [L, R] ranges and the number of duplicates can only be counted once.
Train of Thought: Because there are multiple inquiries, it is definitely time-out for brute force statements, and because it is a problem of range summation, you can consider using a tree array. The tree array can solve the problem of no duplicates, so we can handle this problem specially. First, we can store all the queries, sort the queries by the right endpoint, and then each query. For each query after sorting, we only consider the right endpoint of the range, the last position of each number is recorded. If the number is the same, it must be subtracted from the position of the number.
Code:
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <string. h>
# Include <algorithm>
# Include <map>
# Include <vector>
# Include <string>
# Include <set>
Using namespace std;
Const int n= 50010;
Const int M = 200010;
Int dit [N];
_ Int64 num [N];
_ Int64 ans [M];
Struct interval {
Int lp, rp, id;
} Rr [M];
Bool cmp (interval a, interval B ){
If (a. rp = B. rp)
Return a. lp <B. lp;
Return a. rp <B. rp;
}
Int inline lowbit (int x ){
Return x & (-x );
}
Void inline update (int x, int add ){
While (x <N ){
Num [x] + = add;
X + = lowbit (x );
}
}
_ Int64 inline sum (int x ){
_ Int64 s = 0;
While (x> 0 ){
S + = num [x];
X-= lowbit (x );
}
Return s;
}
Int main (){
Int numcase;
Map <int, int> mp;
Scanf ("% d", & numcase );
While (numcase --){
Int n, m;
Scanf ("% d", & n );
Memset (dit, 0, sizeof (dit ));
For (int I = 1; I <= n; ++ I ){
Scanf ("% d", & dit [I]);
}
Scanf ("% d", & m );
For (int I = 0; I <m; ++ I ){
Scanf ("% d", & rr [I]. lp, & rr [I]. rp );
If (rr [I]. rp <rr [I]. lp)
Swap (rr [I]. lp, rr [I]. rp );
Rr [I]. id = I;
}
Sort (rr, rr + m, cmp );
Memset (num, 0, sizeof (num ));
Memset (ans, 0, sizeof (ans ));
Mp. clear ();
Int rp = 1;
For (int I = 0; I <m; ++ I ){
While (rp <= rr [I]. rp ){
Int x = dit [rp];
If (mp [x]! = 0 ){
Update (mp [x],-x );
}
Update (rp, x );
Mp [x] = rp;
Rp ++;
}
Ans [rr [I]. id] = sum (rr [I]. rp)-sum (rr [I]. lp-1 );
}
For (int I = 0; I <m; ++ I ){
Printf ("% I64d \ n", ans [I]);
}
}
// System ("pause ");
Return 0;
}