for(int i = 1; i <= n; i++)
if(Id[i] != Id[i-1])
group[cnt-1].second = i-1,
group[cnt].first = i;
//cnt 应是 ++cnt
for(int i = group[Id[last_L]].first; i <= group[Id[last_L]].second; i++)
st[i] = ed[i] = 0;
应是
for(int i = /*group[Id[last_L]].first*/l; i <= /*group[Id[last_L]].second*/r; i++)
st[a[i]] = ed[a[i]] = 0;
group[Id[last_L]].first
即块的左端点,右端点同理
if(Id[L] == Id[R])
{//这里应初始化 st 数组
for(int i = L; i <= R; i++)
{
if(st[a[i]] == 0)
st[a[i]] = i;
Ans[id] = max(Ans[id],i-st[a[i]]);
}
for(int i = L; i <= R; i++)
st[a[i]] = 0;
}
应是
if(Id[L] == Id[R])
{
for(int i = L; i <= R; i++)
st[a[i]] = 0;//
for(int i = L; i <= R; i++)
{
if(st[a[i]] == 0)
st[a[i]] = i;
Ans[id] = max(Ans[id],i-st[a[i]]);
}
for(int i = L; i <= R; i++)
st[a[i]] = 0;
}
认真核对这几处:
bool mo(query x,query y)
{
if(Id[x.l] == Id[y.l])
return x.r < y.r;//这里,不能奇偶优化
return Id[x.l] < Id[y.l];
}
void add0(int x)
{
if(!ed0[a[x]]) ed0[a[x]] = x;
ans0 = max(ans0,max(ed[a[x]],ed0[a[x]])-x);
//这行 max(ed[a[x]],ed0[a[x]]) 而不是 ed0[a[x]],原因见第一篇题解
}
祝大家 AC 愉快