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; }
相关文章推荐
- SPOJ 3267. D-query (主席树or树状数组离线)
- SPOJ3267 D-Query 树状数组离线操作 或 主席树 查询某一区间内有多少不同的数
- SPOJ 3267. D-query 主席树
- 【SPOJ3267】D-query-主席树应用
- SPOJ3267:D-query
- SPOJ3267:D-query
- SPOJ 3267(DQUERY) D-query 【主席树】【离线树状数组】
- SPOJ 3267 DQUERY - D-query (主席树)(区间数的种数)
- 【SPOJ3267】D-query-莫队算法
- SPOJ 3267: DQUERY 树状数组,离线算法
- SPOJ3267--D-query (树状数组离线操作)
- [SPOJ 3267] D-query (离线询问+树状数组)
- SPOJ 3267 DQUERY(主席树在线|树状数组离线)
- [SPOJ 3267] D-query (主席树入门)
- SPOJ3267 D-query(主席树模版)
- SPOJ 3267 DQUERY(离线+树状数组)
- spoj 3267 D-query
- SPOJ3267 D-query 离线+树状数组 在线主席树
- SPOJ 3267. D-query (主席树,查询区间有多少个不相同的数)
- SPOJ3267--D-query (主席树入门练习)