HUD-3333 offline + tree array + interval different values and + ideas

This is the first time I have done this kind of question, and I don’t have this kind of thinking, so let’s summarize.
HUD-3333 is a solution to the sum of unique elements in a specified interval. Since the input data is very large and will not be discretized, map is used to map different values.
 

Main idea:

Now given N number sequences A1, A2,..., AN and multiple Queries (i, j) (1≤i≤j≤N). For each Query(i,j), you will calculate the sum of different values ​​in the subsequence Ai, Ai+1,...,Aj.


Input The
first line is an integer T (1≤T≤10), which determines the number of test cases below.
For each case, the input format is as follows:
* Line 1: N (1≤N≤30,000).
*Line 2: N integers A1, A2,..., AN (0≤Ai≤1,000,000,000).
* Line 3: Q (1≤Q≤100,000), the number of queries.
*Next Q rows: Each row contains 2 integers i, j, representing a query (1≤i≤j≤N).

Output
For each query, print the sum of the different values ​​of the specified subsequence in one line.

Sample input
2
3
1 1 4
2
1 2
2 3
5
1 1 2 1 3
3
1 5
2 4
3 5

Sample output
1
5
6
3
6

Ideas:

1. First use a pre[] array, pre[i] represents the subscript of the previous repeat number of the i-th number in the input data. If the i-th number appears for the first time, then pre[i] = 0;

2. Use a map mapping map<long long, int>, which is used to save the position (subscript) of the last occurrence of the current input value, and update the pre;

3. The tree array msum is used to store the sum values ​​that are not repeated in the interval, which is initially empty.

4. Offline all query operations, sort the query operations according to the r of all the question intervals (that is, sort them in the ascending order of the right end of all the question intervals). This ensures that when a large interval covers a small interval, there is no need to recalculate the smaller part.

5. According to the number of offline questions, add the input data one by one to the tree array (the number entered may not necessarily be added to the tree array at the end to reduce unnecessary calculations). If the currently added number is now, its This number has been added before, that is, pre[now] is not 0, delete the previously added number, and re-add the now number. This ensures that each repeated number will be updated one after another after the interval, so that the interval has the property of backward expansion.

6. In the process of adding the tree array, when the interval r of the problem is reached, the interval sum is calculated once. Use the nature of the tree array to calculate.

7. Save the order of the answers in the order of the questions, and finally output them accordingly.

 

AC code:

#include<cstdio> 
#include<cstring>
#include<map>
#include<algorithm>
using namespace std; 
typedef long long ll;
const int maxn = 3e5 + 5;
const int Q = 1e5 + 5;
map<ll ,int>mmp;
ll a[maxn], msum[maxn], ANS[maxn];
int pre[maxn], t, n, q;

struct Node{
	int l, r, id;
}node[Q];//离线问题

bool cmp(Node a, Node b){
	if(a.r == b.r){
		return a.l < b.l;
	}
	return a.r < b.r;
}

void update(int x, ll v){
	for(int i = x;i <= n;i += i & (-i)){
		msum[i] += v;
	}
}

ll getNum(int x){
	ll ans = 0;
	for(int i = x; i > 0;i -= i & (-i)){
		ans += msum[i];
	}
	return ans;
}
 
int main(){
	scanf("%d", &t);
	while(t--){
		memset(msum, 0 ,sizeof msum);
		memset(ANS, 0, sizeof ANS);
		memset(pre, 0, sizeof pre);
		mmp.clear();
		scanf("%d", &n);
		for(int i = 1;i <= n;i++){
			scanf("%lld", a + i);
			pre[i] = mmp[a[i]];
			mmp[a[i]] = i;//保存最后一次出现的位置 
		}
		scanf("%d", &q);
		for(int i = 1;i <= q;i++){
			scanf("%d%d", &node[i].l, &node[i].r);
			node[i].id = i;	//保存提问的顺序,从而保证输出的顺序!!!! 
		}
		sort(node + 1, node + q + 1, cmp);//按r的大小排序 
		int now = 1; //逐个加入 
		for(int i = 1; i <= q;i++){
			while(now <= node[i].r){
				if(pre[now]){
					update(pre[now], -a[now]);
				}
				update(now, a[now]);
				now++;
			}
			ANS[node[i].id] = getNum(node[i].r) - getNum(node[i].l - 1);
		}
		for(int i = 1;i <= q;i++){
			printf("%lld\n",ANS[i]);
		}
	}
	
	return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_40596572/article/details/103995879