题目:http://www.spoj.com/problems/DQUERY/
查询区间的不同数的个数。。
莫队:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
const int N=1000005;
const int M=30005;
int n,q;
int a[M],s[N];
int l,r,tmp;
int pos[M],ans[200001];
int Size;
struct query{
int l,r,id;
}g[200001];
bool cmp(query i,query j){
return pos[i.l]<pos[j.l] || (pos[i.l]==pos[j.l]&&i.r<j.r);
}
inline int add(int r,int val){
r=a[r];
s[r]+=val;
if(s[r]==0 && val==-1) tmp--;
else if(s[r]==1 && val==1) tmp++;
}
int main(){
while(~scanf("%d",&n)){
Size=(int)(sqrt(n+0.5));
clr(s);
for(int i=1;i<=n;i++) pos[i]=(i-1)/Size;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d%d",&g[i].l,&g[i].r);g[i].id=i;
}
sort(g,g+q,cmp);
l=1,r=0,tmp=0;
for(int i=0;i<q;i++){
if(r<g[i].r){
for(r=r+1;r<=g[i].r;r++) add(r,1);
r--;
}
if(r>g[i].r){
for(;r>g[i].r;r--) add(r,-1);
}
if(l>g[i].l){
for(l=l-1;l>=g[i].l;l--) add(l,1);
l++;
}
if(l<g[i].l){
for(;l<g[i].l;l++) add(l,-1);
}
ans[g[i].id]=tmp;
}
for(int i=0;i<q;i++) printf("%d\n",ans[i]);
}
return 0;
}
线段树:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
const int N=1000005;
const int M=30005;
int n,q;
int a[M],s[N];
int ans[200001];
struct query{
int l,r,id;
}g[200001];
bool cmp(query i,query j){
return i.r<j.r;
}
#define L t<<1
#define R t<<1|1
int root[M<<4];
inline void add(int t,int l,int r,int x,int val){
if(l==r) root[t]+=val;
else{
int mid=(l+r)>>1;
if(x<=mid) add(L,l,mid,x,val);
else add(R,mid+1,r,x,val);
root[t]=root[L]+root[R];
}
}
inline int Query(int t,int l,int r,int x,int y){
if(l>=x && r<=y) return root[t];
int mid=(l+r)>>1;
if(y<=mid) return Query(L,l,mid,x,y);
else if(x>mid) return Query(R,mid+1,r,x,y);
else return (Query(L,l,mid,x,mid)+Query(R,mid+1,r,mid+1,y));
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d%d",&g[i].l,&g[i].r);g[i].id=i;
}
sort(g,g+q,cmp);
clr(s),clr(root);
int i=1;
for(int j=0;j<q;j++){
while(i<=g[j].r){
if(s[a[i]]!=0) add(1,1,n,s[a[i]],-1);
add(1,1,n,i,1);
s[a[i]]=i;
i++;
}
ans[g[j].id]=Query(1,1,n,g[j].l,g[j].r);
}
for(int i=0;i<q;i++) printf("%d\n",ans[i]);
}
return 0;
}