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

原创 2015年11月21日 01:26:42

                                                                                                   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;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Light OJ 1188 Fast Queries (树状数组离线)

题目链接: http://lightoj.com/volume_showproblem.php?problem=1188 题意:查找一个区间内不同数字的个数。 分析: 离线做法...

Codeforces 369E Valera and Queries【逆向思维+离线+树状数组】好题!好题!好题!

E. Valera and Queries time limit per test 2 seconds memory limit per test 512 megabytes i...

HLJU 1188 Matrix (二维树状数组)

1118: Matrix Time Limit: 4 Sec  Memory Limit: 128 MB Description 给定一个1000*1000的二维矩阵,初始矩阵中每个数都为1...

BZOJ 1878 【SDOI2009】HH的项链(离线+树状数组)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1878 思路:参考了http://blog.csdn.net/njlcazl/artic...

bzoj 1878 [SDOI2009]HH的项链 树状数组 离线查询

这两场多校都有树状数组+离线查询,之前没做过这种题目,今天做了一道,觉得很妙。 /*     树状数组  区间维护  区间查询  离线查询   经典题     题意:数组大小为N...

【十分不错】【离线+树状数组】【TOJ4105】【Lines Counting】

On the number axis, there are N lines. The two endpoints L and R of each line are integer. Give you ...

hdu4777 求区间内与其它数均互质的数的个数(树状数组+离线处理)

hdu4777 树状数组解题神思想 题意:有n(1 解题思路: 离线处理+树状数组,首先预处理出[1,200000]所有数的质因子,放到have[]里面,然后根据输入的n个数w[],求出每个数的...

HDU 4638 Group 树状数组离线

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意:给定一个长度为n的数组,数组中元素为1到n,询问某个区间内有多少段连续的数字 思路:之前用...

SPOJ DQUERY树状数组离线or主席树

D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit S...

POJ 2761 树状数组离线+离散化 附:线段树解法

#include #include #include #include #include #include #include #include #include #include us...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LightOJ - 1188 Fast Queries(离线树状数组)
举报原因:
原因补充:

(最多只允许输入30个字)