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

Spoj 3267. D-query

2014-05-01 13:56 239 查看
题目: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
;
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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: