如果你用线段树 AC 了 #1 和 #10,你的问题很可能是我说的。
考虑左子树对右子树影响,右子树不能顺手更新,只是合并到节点时考虑影响。
错误示例(更改了右子树):
int calc(int p, long double pre)
{
if(st[p].l==st[p].r)
return st[p].cnt = (st[p].mx > pre);
else
if(st[p*2].mx>pre)
return st[p].cnt = (calc(p*2,pre) + st[p].cnt - st[p*2].cnt);
else
return st[p].cnt = calc(p*2+1,pre);
}
void change(int p, int x, long double d)
{
int mid = st[p].l + st[p].r >> 1;
if(st[p].l==st[p].r)
{
st[p].mx = d;
st[p].cnt = 1;
return;
}
if(x<=mid) change(p*2,x,d);
else change(p*2+1,x,d);
calc(p*2+1,st[p*2].mx);
st[p].cnt = st[p*2].cnt + st[p*2+1].cnt;
st[p].mx = max(st[p*2].mx,st[p*2+1].mx);
}
正确示例:
int calc(int p, long double pre)
{
if(st[p].l==st[p].r)
return st[p].mx > pre;
else
if(st[p*2].mx>pre)
return calc(p*2,pre) + st[p].cnt - st[p*2].cnt;
else
return calc(p*2+1,pre);
}
void change(int p, int x, long double d)
{
int mid = st[p].l + st[p].r >> 1;
if(st[p].l==st[p].r)
{
st[p].mx = d;
st[p].cnt = 1;
return;
}
if(x<=mid) change(p*2,x,d);
else change(p*2+1,x,d);
st[p].cnt = st[p*2].cnt + calc(p*2+1,st[p*2].mx);
st[p].mx = max(st[p*2].mx,st[p*2+1].mx);
}