BZOJ1878 [SDOI2009]HH的项链
2018-01-23 18:42
295 查看
NOIP之前写过这题,先用的分块。
#include<bits/stdc++.h> using namespace std; const int N=50005; int t[N+10],a[N+10]; int v[1000005]; int sum=0; void add(int x) { v[x]++; if(v[x]==1)sum++; } void del(int x) { v[x]--; if(v[x]==0)sum--; } int sq; struct node { int l,r,id; bool operator <(const node &b)const { if((l/sq)==(b.l/sq))return r<b.r; return l<b.l; } }p[200005]; int ans[200005]; int main() { int n;scanf("%d",&n); sq=sqrt((double)n); for(int i=1;i<=n;++i)scanf("%d",&a[i]); int m; scanf("%d",&m); for(int i=1;i<=m;++i) { scanf("%d%d",&p[i].l,&p[i].r); p[i].id=i; } sort(p+1,p+1+m); int l=0,r=0; for(int i=1;i<=m;++i) { while(r>p[i].r)del(a[r--]); while(r<p[i].r)add(a[++r]); while(l<p[i].l)del(a[l++]); while(l>p[i].l)add(a[--l]); ans[p[i].id]=sum; } for(int i=1;i<=m;++i)printf("%d\n",ans[i]); return 0; }
又采用了树状数组,离线按右端点排序,只关心最后一个出现的位置,如果有更新的则将原来的-1将新的位置+1
#include<bits/stdc++.h> using namespace std; const int N=50005; int t[N+10],a[N+10],b[N+10]; int v[N+10]; int lowbit(int x){ return x&(-x); } void add(int x,int y) { for(;x<=N;x+=lowbit(x))t[x]+=y; } int query(int x) { int ans=0;for(;x;x-=lowbit(x))ans+=t[x];return ans; } struct node { int l,r,id; bool operator <(const node &b)const { if(r==b.r)return l<b.l; return r<b.r; } }p[200005]; int ans[200005]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i){scanf("%d",&a[i]);b[i]=a[i];} sort(b+1,b+1+n); for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+n,a[i])-b; int m; scanf("%d",&m); for(int i=1;i<=m;++i) { scanf("%d%d",&p[i].l,&p[i].r); p[i].id=i; } sort(p+1,p+1+m); int pos=1; for(int i=1;i<=m;++i) { while(pos<=p[i].r) { if(v[a[pos]])add(v[a[pos]],-1); v[a[pos]]=pos;add(v[a[pos]],1);pos++; } ans[p[i].id]=query(p[i].r)-query(p[i].l-1); } for(int i=1;i<=m;++i)printf("%d\n",ans[i]); return 0; }
现在我又学了主席树,我们只要对于last(上一次的位置)建主席树,然后查询0~l-1这个区间出现的个数即可。
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; struct node { int l,r,s; }t[N<<2]; int n,m,cnt,last ,pos ,rt ; void change(int &x,int l,int r,int pos) { t[++cnt]=t[x];x=cnt; if(l==r){t[x].s++;return;} int mid=l+r>>1; if(pos<=mid)change(t[x].l,l,mid,pos); else change(t[x].r,mid+1,r,pos); t[x].s=t[t[x].l].s+t[t[x].r].s; return; } int query(int x,int y,int l,int r,int L,int R) { if(l==L&&r==R)return t[y].s-t[x].s; int mid=l+r>>1; if(mid>=R)return query(t[x].l,t[y].l,l,mid,L,R); else if(mid<L)return query(t[x].r,t[y].r,mid+1,r,L,R); return query(t[x].l,t[y].l,l,mid,L,mid)+query(t[x].r,t[y].r,mid+1,r,mid+1,R); } int main() { scanf("%d",&n);int x,l,r; for(int i=1;i<=n;++i) { scanf("%d",&x); last[i]=pos[x]; pos[x]=i; } for(int i=1;i<=n;++i)rt[i]=rt[i-1],change(rt[i],0,n,last[i]); scanf("%d",&m); for(int i=1;i<=m;++i) { scanf("%d%d",&l,&r); printf("%d\n",query(rt[l-1],rt[r],0,n,0,l-1)); } return 0; }
相关文章推荐
- [bzoj 1878][SDOI2009]HH的项链
- [BZOJ1878] [SDOI2009]HH的项链
- 【BZOJ1878】[SDOI2009]HH的项链 树状数组
- BZOJ 1878: [SDOI2009]HH的项链 树状数组 离线维护
- [bzoj1878][SDOI2009][HH的项链] (莫队算法)
- BZOJ1878:[SDOI2009]HH的项链——题解
- bzoj1878 [SDOI2009]HH的项链
- BZOJ 1878 [SDOI2009]HH的项链 (莫队算法)
- 洛谷P1972 [SDOI2009]HH的项链(BZOJ1878)
- 【BZOJ】【1878】【SDOI2009】HH的项链
- BZOJ 1878 【SDOI2009】HH的项链(离线+树状数组)
- BZOJ1878(SDOI2009)[HH的项链]题解--莫队
- BZOJ 1878: [SDOI2009]HH的项链
- BZOJ 1878 [SDOI2009]HH的项链
- bzoj1878 [SDOI2009]HH的项链
- [BZOJ1878][SDOI2009]HH的项链
- bzoj 1878 [SDOI2009]HH的项链(离线处理+BIT)
- 【莫队 or 离线+树状数组】BZOJ1878(SDOI2009)[HH的项链]题解
- 【BZOJ 1878】[SDOI2009]HH的项链 莫队
- 【bzoj1878】[SDOI2009]HH的项链