您的位置:首页 > 产品设计 > UI/UE

SPOJ - DQUERY D-query 离线+树状数组 (区间不同数的个数)

2017-10-03 00:18 337 查看
题目链接

题意:

给你n 个数,给你q个询问,每个询问问你某个区间上不同数的个数是多少?

思路:

q那么大,a[i]最大值为1e6可以想到用离线和BIT来处理.将所有询问记录,按右端点升序排序,对于一个a[i]如果在前面被更新过了,那么就把他删除,在新的位置更新.再处理没超过该范围的所有的区间,最后输出即可.

#include<bits/stdc++.h>
#define P pair<int,int>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e6+10;
int s[maxn],n,q;
int sum[maxn],vis[maxn],a[maxn];
struct node
{
int l,r,id;
bool operator <(const node & w) const
{
return r < w.r;
}
}b[maxn];
int lowbit(int x) {
return x&-x;
}
void add(int x,int d)
{
while(x < maxn)
{
s[x] += d;
x += lowbit(x);
}
return ;
}
int get_sum(int x)
{
int res = 0;
while(x)
{
res += s[x];
x -= lowbit(x);
}
return res;
}
int main(){

while(~scanf("%d",&n))
{
memset(s,0,sizeof s);
memset(vis,0,sizeof vis);
for(int i = 1;i <= n;++i)
{
scanf("%d",&a[i]);
}
scanf("%d",&q);
for(int i = 1;i <= q;++i)
{
scanf("%d %d",&b[i].l,&b[i].r);
b[i].id = i;
}
sort(b+1,b+1+q);
int cur = 1;
for(int i = 1;i <= n &&cur <= q;++i)
{
if(vis[a[i]])
add(vis[a[i]],-1);
vis[a[i]] = i;
add(vis[a[i]],1);
while(cur <= q && b[cur].r <= i)
{
sum[b[cur].id] = get_sum(b[cur].r) - get_sum(b[cur].l-1);
cur++;
}
}
for(int i = 1;i <= q;++i)
printf("%d\n",sum[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: