[BZOJ4241]历史研究(回滚莫队)
2018-11-02 19:03
459 查看
将整个序列分成$\sqrt{n}$块,所有询问按左端点所在块为第一关键字,右端点所在块为第二关键字排序。
当右端点增加或左端点减小时,更新桶与答案。但是左端点增加时需要删除,这时就必须用堆等数据结构维护,复杂度多一个log。
回滚莫队是一个trick:
1.按同样的方法对所有询问排序,每次处理左端点在同一个块中的所有询问。
2.若对于当前询问,右端点和左端点在同一个块中,暴力即可。
3.否则,右端点照常加入更新,左端点先设为块尾,再不断减小,更新答案后再还原至块尾。
这样每次只有左端点减小时才会更新答案,不再需要删除操作。
复杂度分析基本与普通莫队相同。
对于左右端点所属块相同的询问,单次复杂度显然$O(\sqrt{n})$
对于左右端点所属块不同的询问,右端点的处理并没有区别,故总复杂度仍是$(n\sqrt{n})$。左端点每次都只在一个块中移动,故总复杂度也是$(n\sqrt{n})$
#include<cstdio> #include<cstring> #include<algorithm> #define rep(i,l,r) for (int i=(l); i<=(r); i++) typedef long long ll; using namespace std; const int N=100010,B=300; ll ans ; int n,Q,cnt ,a ,b ,bel ; struct P{ int l,r,id; }q ; bool cmp(const P &a,const P &b){ return (bel[a.l]==bel[b.l]) ? a.r<b.r : bel[a.l]<bel[b.l]; } int main(){ freopen("bzoj4241.in","r",stdin); freopen("bzoj4241.out","w",stdout); scanf("%d%d",&n,&Q); rep(i,1,n) scanf("%d",&a[i]),b[i]=a[i],bel[i]=(i-1)/B+1; rep(i,1,Q) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(b+1,b+n+1); int tot=unique(b+1,b+n+1)-b-1; rep(i,1,n) a[i]=lower_bound(b+1,b+tot+1,a[i])-b; sort(q+1,q+Q+1,cmp); int i,j; for (i=1; i<=Q; i=j){ int t=bel[q[i].l],r=min(n,B*t),l=r+1; ll mx=0; memset(cnt,0,sizeof(cnt)); for (j=i; j<=Q && bel[q[j].l]==t; j++){ if (bel[q[j].r]==t){ rep(k,q[j].l,q[j].r) cnt[a[k]]++,mx=max(mx,1ll*b[a[k]]*cnt[a[k]]); rep(k,q[j].l,q[j].r) cnt[a[k]]--; ans[q[j].id]=mx; mx=0; }else{ while (r<q[j].r) cnt[a[++r]]++,mx=max(mx,1ll*b[a[r]]*cnt[a[r]]); ll tmp=mx; while (l>q[j].l) cnt[a[--l]]++,mx=max(mx,1ll*b[a[l]]*cnt[a[l]]); ans[q[j].id]=mx; while (l<=B*t) cnt[a[l++]]--; mx=tmp; } } } rep(i,1,Q) printf("%lld\n",ans[i]); return 0; }
相关文章推荐
- BZOJ.4241.历史研究(回滚莫队 分块)
- BZOJ 4241 历史研究 (回滚莫队)
- [bzoj4241]历史研究 回滚莫队
- 【BZOJ4241】【回滚莫队】历史研究 (非题解的学习分析)
- [BZOJ4241]-历史研究-回滚莫队
- [BZOJ]4241 历史研究 回滚莫队
- BZOJ4241 历史研究 (分块 回滚莫队-教程向)
- bzoj4241 历史研究 (回滚莫队)
- BZOJ4241 历史研究(莫队)
- BZOJ 4241: 历史研究——莫队 二叉堆
- BZOJ4241 历史研究 莫队算法 堆
- bzoj 4241: 历史研究
- [bzoj4241] 历史研究
- bzoj4241 历史研究
- BZOJ 4241 历史研究
- BZOJ 4241 历史研究
- BZOJ4241 历史研究
- [bzoj 4241]历史研究
- BZOJ4241 历史研究
- 【bzoj4241】 历史研究