题解 CF1525C 【Robot Collisions】

SSerxhs

2021-05-17 01:07:41

Solution

首先按位置奇偶分类,只有奇偶性相同才会相撞。 不考虑反弹的情况下,如果记 $\texttt R$ 为 $\texttt ($,$\texttt L$ 为 $\texttt )$,那么碰撞情况等于括号匹配情况,用栈维护即可。 考虑从 $x=0$ 反弹,那么如果当前出现了一个失配的右括号,它不可能与前面的括号匹配,等价于坐标变为 $-x$ 并向右走。因此可以翻转括号并改变坐标,入栈。 考虑从 $x=m$ 反弹,显然是进行完所有括号匹配后剩下的 $\texttt ($ 有一部分反弹,且反弹的恰好为剩下的一半。那么同样坐标变为 $2m-x$ 再翻转括号即可。 ```cpp struct Q { int u,v,w;//坐标,是否为 L,原下标 bool operator<(const Q &o) const {return u<o.u;} }; void cal() { sort(a+1,a+n+1);tp=0; for (i=1;i<=n;i++) if (a[i].v) { if (!tp) { a[i].u=-a[i].u;a[i].v=0; st[++tp]=a[i]; } else { ans[a[i].w]=ans[st[tp].w]=a[i].u-st[tp].u>>1; --tp; } } else { st[++tp]=a[i]; } if (tp<=1) return; if (tp&1) {for (i=1;i<tp;i++) st[i]=st[i+1];--tp;} for (i=2;i<=tp;i+=2) st[i].u=2*m-st[i].u; for (i=1;i<=tp;i+=2) ans[st[i].w]=ans[st[i+1].w]=st[i+1].u-st[i].u>>1; } ```