主席树|线段树(区间不同的数的个数)spoj3267
来源:互联网 发布:用友软件集团 编辑:程序博客网 时间:2024/05/21 10:50
3267. D-query
Problem code: DQUERY
EnglishVietnamese
Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.
Input
- Line 1: n (1 ≤ n ≤ 30000).
- Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
- Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
- In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).
Output
- For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.
Example
Input51 1 2 1 331 52 43 5Output323
首先是线段树解法,跟hdu上的几个题是一样的
#include<stdio.h> #include<algorithm> #include<string.h> #include<map> #define N 35000 #define M 250000 using namespace std; struct node { int x,y,id; }b[M]; int c[N],ans[M],a[N]; map<int ,int >ma; bool cmp(node a,node b) { return a.y<b.y; } int lowbit(int x) { return x&(-x); } void update(int x,int val) { while(x<=N) { c[x]+=val; x+=lowbit(x); } } int sum(int x) { int s=0; while(x) { s+=c[x]; x-=lowbit(x); } return s; } int main() { int n,i,m,pre,j; //freopen("a.txt","r",stdin); while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(i=0;i<m;i++) { scanf("%d%d",&b[i].x,&b[i].y); b[i].id=i; } sort(b,b+m,cmp); pre=1; memset(c,0,sizeof(c)); for(i=0;i<m;i++) { for(j=pre;j<=b[i].y;j++) { if(ma.find(a[j])==ma.end()) update(j,1); else { update(ma[a[j]],-1); update(j,1); } ma[a[j]]=j; } ans[b[i].id]=sum(b[i].y)-sum(b[i].x-1); pre=b[i].y+1; } for(i=0;i<m;i++) printf("%d\n",ans[i]); } return 0; }
然后是主席树,主席树保存前缀1...i出现在1...n的数有多少
查询的时候对于(l,r),之需要查询T[r]这个数,1...l有多少个不同的数,然后用总数减掉就可以了
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=30010;const int maxm=maxn*100;int n,q,m,num;int a[maxn];int cnt[maxm],lson[maxm],rson[maxm];int T[maxm];map<int,int> vis;int build(int l,int r){ int root=num++; cnt[root]=0; if(l!=r) { int mid=(l+r)>>1; lson[root]=build(l,mid); rson[root]=build(mid+1,r); } return root;}int update(int root,int pos,int val){ int newroot=num++,tmp=newroot; int l=1,r=n; cnt[newroot]=cnt[root]+val; while(l<r) { int mid=(l+r)>>1; if(pos<=mid) { r=mid; lson[newroot]=num++,rson[newroot]=rson[root]; newroot=lson[newroot],root=lson[root]; } else { l=mid+1; rson[newroot]=num++;lson[newroot]=lson[root]; newroot=rson[newroot],root=rson[root]; } cnt[newroot]=cnt[root]+val; } return tmp;}int query(int root,int pos){ int l=1,r=n,ans=0; while(pos>l) { int mid=(l+r)>>1; if(pos<=mid) { r=mid; root=lson[root]; } else { l=mid+1; ans+=cnt[lson[root]]; root=rson[root]; } } return ans;}int main(){ while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++)scanf("%d",&a[i]); scanf("%d",&q); num=0; vis.clear(); T[0]=build(1,n); for(int i=1;i<=n;i++) { if(vis.count(a[i])) { int tmp=update(T[i-1],vis[a[i]],-1); T[i]=update(tmp,i,1); } else { T[i]=update(T[i-1],i,1); } vis[a[i]]=i; } while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",cnt[T[r]]-query(T[r],l)); } } return 0;}
0 0
- 主席树|线段树(区间不同的数的个数)spoj3267
- SPOJ3267 D-Query 树状数组离线操作 或 主席树 查询某一区间内有多少不同的数
- SPOJ DQUERY 区间内不同数的个数 主席树
- hdu 5919 Sequence II(主席树,求区间不同数的个数)
- SPOJ DQUERY 求区间内不同数的个数 (主席树)
- SPOJ D-query 主席树在线(求区间不同的数的个数)
- SPOJ DQUERY 求区间内不同数的个数 主席树
- spoj 3267. D-query 主席树求区间不同数的个数
- SPOJ D-query 区间不同数的个数 [在线主席树 or 离线树状数组]
- spoj DQUERY - D-query(区间不同数的个数 主席树 or BIT)
- hdu 5919 Sequence II (主席树,求区间不同数的个数)
- hdu 5790 prefix 主席树在线维护区间不同数的个数
- SPOJ3267--D-query(离线线段树||在线主席树)
- 线段树离线处理(区间内不同的数的个数)hdu3333
- SPOJ-DQUERY-主席树求区间不同数个数模板
- 主席树-查询区间有多少个不同的数
- hdu 5919 主席树(区间不同数个数+区间第k个数)
- SPOJ DQUERY(树状数组离线处理 or 主席树 区间不同数个数)
- Pragma Exception_init 的用法
- Spring实战笔记5---事务管理
- CRM系统数据挖掘
- android shape的使用
- 创建声卡
- 主席树|线段树(区间不同的数的个数)spoj3267
- 首页 网站运维 CentOS 下如何修改 MySQL 的密码 CentOS 下如何修改 MySQL 的密码
- LINUX 字符设备自动创建文件节点
- Makefile 连接静态库注意事项
- 学习jQuery的免费资源:电子书、视频、教程和博客
- Sublime Text2 配置
- Oracle异常总览
- 上位机与arm串口通信实验
- 背包问题