关闭

LightOJ - 1188 Fast Queries(离线树状数组)

标签: LightOJ - 1188 Fast离线树状数组
611人阅读 评论(1) 收藏 举报
分类:

                                                                                                   Fast Queries

Given an array of N integers indexed from 1 to N, and q queries, each in the form i j, you have to find the number of distinct integers from index i to j(inclusive).

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

The first line of a case is a blank line. The next line contains two integers N (1 ≤ N ≤ 105)q (1 ≤ q ≤ 50000). The next line contains N space separated integers forming the array. There integers range in [0, 105].

Each of the next q lines will contain a query which is in the form i j (1 ≤ i ≤ j ≤ N).

Output

For each test case, print the case number in a single line. Then for each query you have to print a line containing number of distinct integers from index i to j.

Sample Input

Output for Sample Input

1

 

8 5

1 1 1 2 3 5 1 2

1 8

2 3

3 6

4 5

4 8

Case 1:

4

1

4

2

4

Note


题意:求区间不同数的个数。

题解:离线树状数组。把查询区间按右区间升序排序,然后把数组逐个插入,

          对于当前a[i],如果之前出现过了,则把上次出现的位置 -1,当前位置 +1.

          然后若有查询区间的右区间等于i,查询该区间,把答案保存下来。

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <map>
#include <iostream>

using namespace std;
const int N = 100010;

int n,q;
struct node {
    int l,r;
    int id;
} Q[N*5];

int vis[N],a[N];
int ans[N*5];

bool cmp(node a,node b) {
    return a.r<b.r;
}

int bit[N];

void add(int i,int v) {
    while(i<=n) {
        bit[i]+=v;
        i+=i&-i;
    }
}

int sum(int i) {
    int res=0;
    while(i>0) {
        res+=bit[i];
        i-=i&-i;
    }
    return res;
}

int main() {
    //freopen("test.in","r",stdin);
    int t,ca=1;
    cin>>t;
    while(t--) {
        scanf("%d%d",&n,&q);
        for(int i=1; i<=n; i++)scanf("%d",&a[i]);
        for(int i=1; i<=q; i++) {
            scanf("%d%d",&Q[i].l,&Q[i].r);
            Q[i].id=i;
        }
        sort(Q+1,Q+q+1,cmp);
        memset(bit,0,sizeof bit);
        memset(vis,0,sizeof vis);
        int la=1;
        for(int i=1; i<=n; i++) {
            add(i,1);
            if(vis[a[i]])add(vis[a[i]],-1);
            vis[a[i]]=i;
            while(la<=q&&Q[la].r==i) {
                ans[Q[la].id]=sum(Q[la].r)-sum(Q[la].l-1);
                la++;
            }
            if(la>q)break;
        }
        printf("Case %d:\n",ca++);
        for(int i=1; i<=q; i++) {
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:151861次
    • 积分:4416
    • 等级:
    • 排名:第7039名
    • 原创:294篇
    • 转载:16篇
    • 译文:0篇
    • 评论:13条
    文章分类
    最新评论