欢迎光临散文网 会员登陆 & 注册

牛客竞赛题目讲解_Different Integers(树状数组)

2022-04-24 10:40 作者:Clayton_Zhou  | 我要投稿

//  https://ac.nowcoder.com/acm/contest/20322/J  

#include <algorithm>

#include <iostream>

#include <cstring>

 #include <vector>

 #define endl '\n'

 

using namespace std;

const int maxn = 1e5 + 9; 

int n, m;

int first[maxn], lst[maxn], a[maxn], ans[maxn];

int cnt;

int c[maxn];

struct node{

    int l, r, id;

    bool operator<(const node &B){

        return r < B.r;

    }

}d[maxn];

 // 树状数组更新

/*

for(  i=1;i<=16;i++)

        printf("i =%2d,i&(-i) =%2d\n",i,i&(-i));

i&(-i) 给出 i 最低位的权重

*/

void update(int i, int k){

    while(i <= n) c[i] += k, i += i & (-i);    // 父节点

}

int qry(int i){

    int ans = 0;

    // 子节点, 如果i=3, 下一个节点为i=2

    while(i) ans += c[i], i -= i & (-i);    

    return ans; 

}

 

void work()

{

     cnt = 0;

    memset(first,0 ,sizeof first);

     memset(lst,0 ,sizeof lst);

    memset(c,0 ,sizeof c);

    

    for(int i = 1; i <= n; ++i){

        cin >> a[i];

        if(!first[a[i]]) first[a[i]] = i, ++cnt;

        lst[a[i]] = i;  

    }

    for(int i = 1; i <= m; ++i){

        cin >> d[i].l >> d[i].r;

        d[i].id = i;

    }

    sort(d + 1, d + 1 + m);

    int j = 1;

    for(int i = 1; i <= n; ++i){

        while(i == d[j].r && j <= m){// 因为数据包含 [r,n],所以先求答案再更新 

            ans[d[j].id] = cnt + qry(d[j].l);

            ++j;    // j不能减少,所以按照d[j].r排序

        }

        if(lst[a[i]] == i){

            update(first[a[i]], 1);

            --cnt;

        }

    }

    for(int i = 1; i <= m; ++i) //cout << ans[i] << endl;

       printf("%d\n" ,ans[i] );

int main()

{   

    while(cin >> n >> m)

    work();

    return 0;

}


牛客竞赛题目讲解_Different Integers(树状数组)的评论 (共 条)

分享到微博请遵守国家法律