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;
}
题意:
给你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;
}
相关文章推荐
- SPOJ DQUERY D-query(离线线段树,查区间不同数字个数)
- SPOJ DQUERY (主席树求区间不同数个数)
- SPOJ:D-query(非常规主席树求区间不同数的个数)
- SPOJ DQUERY 求区间内不同数的个数 主席树
- D-query SPOJ - DQUERY 查询区间有多少个不同的数(SPOJ DQUERY)
- [spoj D-query] 主席树求区间不同数
- SPOJ DQUERY 区间内不同数的个数
- SPOJ D-query(区间不同的数的个数)
- SPOJ DQUERY(树状数组离线处理 or 主席树 区间不同数个数)
- SPOJ DQUERY 区间内不同数的个数
- SPOJ - DQUERY 主席树求区间中不同数字的个数
- SPOJ DQUERY - D-query(主席树-区间不同数的个数)
- SPOJ D-query 区间不同数的个数 [在线主席树 or 离线树状数组]
- 【SPOJ 】 DQUERY 【莫队 - 区间几个不同数字】
- SPOJ DQUERY - D-query(主席树 ,求区间不同的数个数)
- SPOJ-DQUERY - D-query (主席树 区间不同数个数)
- SPOJ D-query 主席树在线(求区间不同的数的个数)
- SPOJ DQUERY 求区间内不同数的个数 (主席树)
- spoj D-query 区间不同数个数 主席树||离线+树状数组
- spoj DQUERY - D-query(区间不同数的个数 主席树 or BIT)