P1972 [SDOI2009] HH的项链(莫队)
2017-03-29 14:41
323 查看
https://www.luogu.org/problem/show?pid=1972#sub
时间复杂度证明:
右端点移动:
首先我们考虑一个块里面的转移情况
由于一个块里面的询问都按右端点排序
所以我们右端点在一个块里面最多移动n次
有 O(n√)O(n)个块,那么同一个块内的右端点移动最多就是O(nn√)O(nn)
然后考虑从一个块到另一个块导致的右端点变化
最坏情况,右端点由n到1,那么移动n次
有 O(n√)O(n)个块
那么从一个块到另一个块的事件只会发生O(n√)O(n)次……
所以这种右端点移动的次数也是O(nn√)O(nn)次
没有别的事件导致右端点移动了
左端点移动:
同一个块里面,由于左端点都在一个长度为O(n√)O(n)的区间里面
所以在同一块里面移动一次,左端点最多变化O(n√)O(n)
总共有n个询问……
所以同一块里面的移动最多n次
那么同一个块里面的左端点变化最多是O(nn√)O(nn)的
考虑跨越块
每由第i个块到第i+1个块,左端点最坏加上O(n√)O(n)
总共能加上O(n√)O(n)次
所以跨越块导致的左端点移动是O(n)O(n)的
综上,分块做法是O(n∗n√)O(n∗n)。
时间复杂度证明:
右端点移动:
首先我们考虑一个块里面的转移情况
由于一个块里面的询问都按右端点排序
所以我们右端点在一个块里面最多移动n次
有 O(n√)O(n)个块,那么同一个块内的右端点移动最多就是O(nn√)O(nn)
然后考虑从一个块到另一个块导致的右端点变化
最坏情况,右端点由n到1,那么移动n次
有 O(n√)O(n)个块
那么从一个块到另一个块的事件只会发生O(n√)O(n)次……
所以这种右端点移动的次数也是O(nn√)O(nn)次
没有别的事件导致右端点移动了
左端点移动:
同一个块里面,由于左端点都在一个长度为O(n√)O(n)的区间里面
所以在同一块里面移动一次,左端点最多变化O(n√)O(n)
总共有n个询问……
所以同一块里面的移动最多n次
那么同一个块里面的左端点变化最多是O(nn√)O(nn)的
考虑跨越块
每由第i个块到第i+1个块,左端点最坏加上O(n√)O(n)
总共能加上O(n√)O(n)次
所以跨越块导致的左端点移动是O(n)O(n)的
综上,分块做法是O(n∗n√)O(n∗n)。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; struct H{ int l,r,id,qv; }Q[200009]; int a[50009],n,m,limit,sum=0; int num[1000009],ans[200009]; int my_comp(const H&a,const H&b) { if(a.qv<b.qv) return 1;//根据左端点分块 if(a.qv>b.qv) return 0; if(a.r<b.r) return 1;//在块内按照r升序 return 0; } void add(int x) { num[x]++; if(num[x]==1) sum++;// } void del(int x) { num[x]--; if(num[x]==0) sum--;// } int main() { scanf("%d",&n);limit=(int)(sqrt((double)(n)+0.5)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].qv=Q[i].l/limit;Q[i].id=i;//id 为第几个询问,离线输出 } sort(Q+1,Q+m+1,my_comp); int r=0,l=0; for(int i=1;i<=m;i++) { while(r<Q[i].r){ r++; add(a[r]); } while(r>Q[i].r){ r--; del(a[r+1]); } while(l<Q[i].l){ l++; del(a[l-1]); } while(l>Q[i].l){ l--; add(a[l]); } ans[Q[i].id]=sum; } for(int i=1;i<=m;i++) { printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
- 洛谷 P1972 [SDOI2009]HH的项链 主席树 or 莫队算法
- 【SDOI2009】HH的项链 莫队
- 【主席树|莫队|离线树状数组】BZOJ1878 [SDOI 2009]HH的项链
- BZOJ 1878 [SDOI2009]HH的项链 莫队
- 【SDOI2009】HH的项链 (莫队)
- 洛谷 P1972 [SDOI2009]HH的项链
- AC日记——[SDOI2009]HH的项链 洛谷 P1972
- 洛谷 P1972 [SDOI2009]HH的项链
- BZOJ 1878: [SDOI2009]HH的项链 | 莫队
- BZOJ_P1878&Codevs_P2307 [SDOI2009]HH的项链(莫队算法)
- P1972 [SDOI2009]HH的项链
- Bzoj 1878: [SDOI2009]HH的项链 莫队
- luoguP1972 [SDOI2009]HH的项链(莫队)
- BZOJ1878(SDOI2009)[HH的项链]题解--莫队
- P1972 [SDOI2009]HH的项链
- 【莫队 or 离线+树状数组】BZOJ1878(SDOI2009)[HH的项链]题解
- bzoj 1878: [SDOI2009]HH的项链(莫队算法)
- [SDOI2009][bzoj1878] HH的项链 [莫队模板题]
- BZOJ_1878_[SDOI2009]HH的项链_莫队