【BZOJ】4358: permu 莫队算法
2018-03-14 18:58
239 查看
【题意】给定长度为n的排列,m次询问区间[L,R]的最长连续值域。n<=50000。
【算法】莫队算法
【题解】考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[x]表示数值x往下延伸的最大长度。
增加一个数x时,up[x]=up[x+1]+1,down[x]=down[x-1]+1。令t=up[x]+down[x]+1,可以用于更新答案。
同时,增加x后会影响到x所在连续区间最大数和最小数,中间的数字不会影响后面的答案(因为只考虑加数,中间的数字虽然改变但不会被调用),所以有:
down[x+up[x]-1] = up[x-down[x]+1] = t
回顾莫队算法的复杂度分析。莫队算法按左端点分块,块内按右端点排序。假设块大小为B,左端点复杂度O(B*q),右端点复杂度O(n/B*n)。
实际上,我们只需要保证每次询问左端点复杂度为O(B),每一块询问右端点复杂度为O(n)就可以了。
既然只需要每次询问左端点复杂度为O(B),干脆不用删点的操作实现,改成暴力加点实现。
记块的右端点的r,对于同一块的询问,将>r的右端点逐渐增加向右扩展并累计。对于每次询问,暴力增加块内的部分至询问左端点处,用栈记录修改,做完后清除。
复杂度O(n√m)。
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=50010; int a[maxn],ANS[maxn],s1[maxn*2],s2[maxn*2],up[maxn],down[maxn],top,ans,answer; int n,m; struct cyc{int l,r,q,id;}b[maxn]; bool cmp(cyc x,cyc y){return x.q^y.q?x.q<y.q:x.r<y.r;} void modify(int x){ up[x]=up[x+1]+1; down[x]=down[x-1]+1; int t=up[x]+down[x]-1; s1[++top]=x+up[x]-1;s2[top]=down[s1[top]]; s1[++top]=x-down[x]+1;s2[top]=up[s1[top]]; down[s1[top-1]]=up[s1[top]]=t; ans=max(ans,t); } int main(){ scanf("%d%d",&n,&m); int Q=(int)(1.0*n/sqrt(m)); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=m;i++){scanf("%d%d",&b[i].l,&b[i].r);b[i].q=(b[i].l-1)/Q+1;b[i].id=i;} sort(b+1,b+m+1,cmp); int r=0,t=0; for(int i=1;i<=m;i++){ if(b[i].q!=b[i-1].q){ memset(up,0,sizeof(up)); memset(down,0,sizeof(down)); t=r=b[i].q*Q;answer=0; } ans=0;top=0; while(b[i].r>r)modify(a[++r]); top=0;//forget... answer=ans=max(answer,ans); for(int j=b[i].l;j<=min(t,b[i].r);j++)modify(a[j]); ANS[b[i].id]=ans; for(int j=top;j>=1;j--)if(j%2)down[s1[j]]=s2[j];else up[s1[j]]=s2[j]; for(int j=b[i].l;j<=min(t,b[i].r);j++)up[a[j]]=down[a[j]]=0; } for(int i=1;i<=m;i++)printf("%d\n",ANS[i]); return 0; }View Code
注意:栈数组开2倍
还有想着后面要记得写的东西可以先写到草稿纸上,不然后面忘了……GG
相关文章推荐
- bzoj 4358: permu (莫队+栈||KD-tree||莫队+线段树)
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) (莫队算法)
- [bzoj 2038 OR 清橙A1206 小Z的袜子]莫队算法
- BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
- BZOJ - 4810 [Ynoi2017]由乃的玉米田 莫队算法 + bitset 大暴力
- 【莫队算法】【权值分块】bzoj2223 [Coci 2009]PATULJCI
- BZOJ 2038 2009国家集训队 小Z的袜子 莫队算法
- 【模板】BZOJ 3781: 小B的询问 莫队算法
- BZOJ_2038 小Z的袜子(莫队算法)
- BZOJ 4358 坑 莫队+线段树 死T
- BZOJ 1878 [SDOI2009]HH的项链——离线+树状数组||莫队算法
- 【DFS序】【莫队算法】【权值分块】bzoj2809 [Apio2012]dispatching
- bzoj 2120: 数颜色(带修改的莫队算法)
- [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)
- BZOJ 2038 小Z的袜子 莫队算法(模板题)
- 树上(带修改)莫队算法-- bzoj4129 && bzoj3757
- BZOJ 3289 Mato的文件管理 莫队算法+树状数组
- BZOJ_P2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ 4358 坑 莫队+线段树 死T
- BZOJ 2038 (莫队算法)