Seeking the number of different numbers in the interval (Fenwick tree)

Casual working

To a sequence, so that you find the number [l, r] in the different figures

Entry

Input a n, followed by a sequence containing n digital

Enter a q, followed by two integer representing the query interval

Export

The results of the query q

Sample

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 

Thinking

Before the sequence number of the i-th digit, different numbers of recording a tree array.

A query from the left side of the interval start scanning:

1. 数字首次出现时,当前位置加一,且用map记录下当前数字出现的位置
2. 数字非首次出现时,当前位置加一,但是上次出现的位置要减一

After a query interval getsum(r) - getsum(l - 1)is the answer.

Think carefully about the above process, when performing the second case, previous results will be destroyed, so the whole sequence scanning process must ensure that once completed.

So pay attention:

1. 按照查询区间的右端点值进行排序(当前的会破坏前面的结果)
2. 保证整个序列中的元素仅扫描一次,即代码中的`pre = query[i].r + 1;`而不是`pre = query[i + 1].l;`

Code

#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 10000;
int n = 0, q = 0;

struct Query{
    int id, l, r;
    bool operator< (Query a) const{
        return r < a.r;
    }
}query[maxn];



int v[maxn], sum[maxn], ans[maxn];

int lowbit(int x){
    return x & (-x);
}

void change(int i, int a){
    while(i <= n){
        sum[i] += a;
        i += lowbit(i);
    }
}

int getsum(int i){
    int sum_t = 0;
    while(i > 0){
        sum_t += sum[i];
        i -= lowbit(i);
    }
    return sum_t;
}

int main() {
    
    while(~scanf("%d", &n)){
        memset(v, 0, sizeof(v));
        memset(sum, 0, sizeof(sum));
        memset(ans, 0, sizeof(ans));
        
        int t = 0;
        for(int i = 1; i <= n; i++){
            scanf("%d", &v[i]);
        }
        scanf("%d", &q);
        for(int i = 1; i <= q; i++){
            scanf("%d%d", &query[i].l, &query[i].r);
            query[i].id = i;
        }
        sort(query + 1, query + q + 1);
        
        int pre = 1;
        map<int, int> mymap;
        for(int i = 1; i <= q; i++){
            for(int j = pre; j <= query[i].r; j++){
                //已存在 
                if(mymap[v[j]]){
                    change(mymap[v[j]], -1);
                }
                mymap[v[j]] = j;
                change(j, 1);
            }
            pre = query[i].r + 1;
            ans[query[i].id] = getsum(query[i].r) - getsum(query[i].l - 1);
        }
        
        for(int i = 1; i <= q; i++){
            cout << ans[i] << endl;
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/woxiaosade/p/12305677.html