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

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.

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

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++) {
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条
文章分类
阅读排行
最新评论