社区讨论
萌新刚学回滚莫队,4pts剩下全T求调
P5906【模板】回滚莫队&不删除莫队参与者 3已保存回复 25
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 25 条
- 当前快照
- 1 份
- 快照标识符
- @lo1ss81s
- 此快照首次捕获于
- 2023/10/23 02:23 2 年前
- 此快照最后确认于
- 2023/11/03 03:00 2 年前
完全是自己摸索的带修莫队,求大佬帮忙看一眼代码吧,问题解决了一定关注。TLE原因(应该)不是常数问题,因为每一个没过的测试点都高达1.2s以上
手动打个注释:
- sl是段长
- sid是段号
- el、er是现在区间第从左/右一个该元素的序号
- maxd是维护的当前区间的答案
- bpl、bpr、bpd都是备份的数据(实在不好解决冲突问题才维护了bpr QAQ)
- l、r是当前查询的区间
- 函数force是暴力统计某个区间答案
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cctype>
#include <cmath>
#define inf 0x3f3f3f3f
using namespace std;
struct qry
{
int l,r,id,ans;
friend bool operator < (qry a,qry b)
{
return a.id<b.id;
}
}q[200005];
int n,m,sl,a[200005],lnk[200005],an,sid[200005],el[200005],er[200005],bpl[20005],bpr[20005],bpd,maxd,l,r;
inline void read(int &x)
{
char c=getchar();x=0;
while(!isdigit(c)) x=getchar();
while(isdigit(c)) x=x*10+c-48,c=getchar();
}
inline bool sty(qry a,qry b)
{
if(sid[a.l]^sid[b.l]) return a.l<b.l;
return a.r<b.r;
}
inline int tai(int s){return s*sl;}
inline int hea(int s){return tai(s-1)+1;}
inline void add(int x,int p,bool d) //d=0:from left | d=1:from right
{
if(el[x]==p) return;
if(el[x]==inf&&er[x]==0) el[x]=er[x]=p;
else
if(d) er[x]=p;
else if(!d) el[x]=p;
maxd=max(maxd,er[x]-el[x]);
}
inline void force()
{
for(int i=l;i<=r;i++)
{
if(el[a[i]]>=inf) el[a[i]]=i;
else maxd=max(maxd,i-el[a[i]]),er[a[i]]=i;
}
}
inline void backup()
{
for(int i=tai(sid[l]);i<=r;i++)
{
if(bpl[a[i]]>=inf) bpl[a[i]]=i;
else bpd=max(bpd,i-bpl[a[i]]),bpr[a[i]]=i;
}
}
inline void reload()
{
for(int i=l;i<=tai(sid[l])-1;i++) el[a[i]]=bpl[a[i]],er[a[i]]=bpr[a[i]];
maxd=bpd;
l=tai(sid[l]);
}
inline void clear()
{
maxd=bpd=0;
for(int i=hea(sid[l]);i<=r;i++) el[a[i]]=bpl[a[i]]=inf,er[a[i]]=bpr[a[i]]=0;
}
int main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i]);
read(m);
sl=n/sqrt((m<<1)/3);
for(int i=1;i<=m;i++) read(q[i].l),read(q[i].r),q[i].id=i,lnk[i]=a[i];
sort(lnk+1,lnk+n+1);an=unique(lnk+1,lnk+n+1)-lnk-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(lnk+1,lnk+an+1,a[i])-lnk,sid[i]=(i-1)/sl+1;
sort(q+1,q+m+1,sty);
for(int i=1;i<=an;i++) el[i]=bpl[i]=inf;
l=inf;r=0;
for(int i=1;i<=m;i++)
{
if(sid[q[i].l]==sid[q[i].r])
{
l=q[i].l;r=q[i].r;
clear();
force();
q[i].ans=maxd;
r=0;
}
else if(sid[q[i].l]^sid[l]||!r)
{
if(!r) r=q[i].r;clear();
l=q[i].l;r=q[i].r;force();backup();
q[i].ans=maxd;
}
else
{
reload();
while(r<q[i].r) r++,add(a[r],r,1);
while(l>q[i].l) l--,add(a[l],l,0);
q[i].ans=maxd;
}
}
sort(q+1,q+m+1);
for(int i=1;i<=m;i++) printf("%d\n",q[i].ans);
return 0;
}
(他好像吞我缩进 恼火)
回复
共 25 条回复,欢迎继续交流。
正在加载回复...