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

SPOJ D-query(区间不同的数的个数)

2017-08-14 19:29 323 查看
题目

离线:树状数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=(int)3e4+10;
struct node{
int l,r,idx;
}qu[200010];
bool cmp(const node &a,const node &b){
return a.r<b.r;
}
vector<int>v;
int a[MAXN],pre[MAXN],mark[MAXN];
int ans[200010];
int p[MAXN];
int n;
void add(int x,int y){
while(x<=n){
p[x]+=y;
x+=x&(-x);
}
}
int getsum(int x){
ll re=0;
while(x){
re+=p[x];
x-=x&(-x);
}
return re;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
for(int i=1;i<=n;i++){
a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
pre[i]=mark[a[i]];
mark[a[i]]=i;
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&qu[i].l,&qu[i].r);
qu[i].idx=i;
}
sort(qu+1,qu+1+m,cmp);
int tmp=0;
for(int i=1;i<=m;i++){
while(tmp<qu[i].r){
tmp++;
if(pre[tmp]==0){
add(1,1);
add(tmp+1,-1);
}
else {
add(pre[tmp]+1,1);
add(tmp+1,-1);
}
}
ans[qu[i].idx]=getsum(qu[i].l);
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
return 0;
}

在线:主席树
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=30005;
int a[MAXN],n,m,vsz,pre[MAXN];
vector<int>v;
int root[MAXN],ls[MAXN*40],rs[MAXN*40],add[MAXN*40],tot;
void build(int l,int r,int &rt){
rt=++tot;
if(l==r)return;
int mid=l+r>>1;
build(l,mid,ls[rt]);
build(mid+1,r,rs[rt]);
}
void insert(int l,int r,int x,int y,int &r1,int r2){
r1=++tot;ls[r1]=ls[r2];rs[r1]=rs[r2];add[r1]=add[r2];
if(l==x&&r==y){add[r1]++;return ;}
int mid=l+r>>1;
if(mid>=y)insert(l,mid,x,y,ls[r1],ls[r2]);
else if(mid<x)insert(mid+1,r,x,y,rs[r1],rs[r2]);
else insert(l,mid,x,mid,ls[r1],ls[r2]),insert(mid+1,r,mid+1,y,rs[r1],rs[r2]);
}
int query(int l,int r,int x,int rt){
if(l==r)return add[rt];
int mid=l+r>>1;
if(x<=mid)return add[rt]+query(l,mid,x,ls[rt]);
else return add[rt]+query(mid+1,r,x,rs[rt]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
vsz=v.size();
build(1,n,root[0]);
for(int i=1;i<=n;i++){
a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
insert(1,n,pre[a[i]]+1,i,root[i],root[i-1]);
pre[a[i]]=i;
}
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(1,n,l,root[r]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: