这是本文档旧的修订版!
题目 | 蒋贤蒙 | 王赵安 | 王智彪 |
---|---|---|---|
A | 0 | 0 | 0 |
B | 2 | 0 | 0 |
C | 0 | 0 | 0 |
D | 0 | 0 | 0 |
E | 0 | 0 | 0 |
G | 0 | 0 | 0 |
J | 2 | 0 | 0 |
K | 0 | 0 | 0 |
给定一个序列 $A$ 和序列 $B$,其中 $0\le b_i\le 1$ 接下来三种操作:
对每个操作 $3$,输出 $b_{i_t}\neq b_{i_{t+1}}$ 的个数。
设 $ma(L,R)=\max(a[L\sim R]),mb(L,R)$ 表示 $ma(L,R)$ 对应的 $b_i$,如果存在多个就取最右边的。
设 $\text{query}(L,R,p,q)$ 表示假如当前序列末尾对应 $a_i=p,b_i=q$ 时遍历区间 $(L,R)$ 得到的答案。
于是,如果 $a_i\gt ma(L,M)$,则 $\text{query}(L,R,p,q)=\text{query}(M+1,R,p,q)$。
否则,有 $\text{query}(L,R,p,q)=\text{query}(L,M,p,q)+\text{query}(M+1,R,ma(L,M),mb(L,M))$。
建立线段树,每个区间维护 $\text{query}(M+1,R,ma(L,M),mb(L,M))$。
这样,对一个询问,如果该询问正好对应一个线段树区间,则查询复杂度 $O(\log n)$。
否则,将该询问拆分成 $O(\log n)$ 个线段树区间,串联查询计算答案,时间复杂度 $O(\log^2 n)$。
对与修改操作,修改完暴力询问更新 $\text{query}(M+1,R,ma(L,M),mb(L,M))$,由于这是线段树区间,所以复杂度为 $O(\log n)$。
所以修改的总复杂度也是 $O\left(\log^2 n\right)$。总时间复杂度 $O\left(n\log n+q\log^2 n\right)$。
ps. 比赛写了 $O(nq)$ 的假算法,居然过了。
给定一个有向图,初始时 $\text{dis}(u,u)=0,\text{dis}(u,v)=\infty(u\neq v)$。
接下来给定若干条边 $(u,v,w)$,使得 $\text{dis}(u,v)=w$。询问以下两个程序最终结果中满足 $\text{dis}(u,v)$ 相同的 $(u,v)$ 对数。
for k from 1 to n for i from 1 to n for j from 1 to n dis[i][j] <- min(dis[i][j], dis[i][k] + dis[k][j])
for i from 1 to n for j from 1 to n for k from 1 to n dis[i][j] <- min(dis[i][j], dis[i][k] + dis[k][j])
首先 $n$ 次单点源最短路算法 $O(nm\log m)$ 求出 $\text{dis}$ 的真实值。
设 $ok(u,v)$ 表示 $\text{dis}(u,v)$ 是否为正确值,考虑第二个程序得到的 $\text{dis}(i,j)$ 正确的充要条件。
不难发现,只要 $i\to j$ 的最短路上有一点 $k$ 满足 $ok(i,k)\And ok(k,j)$ 即可。
首先考虑找到所有满足条件的 $k$,设 $\text{path}(u,v)$ 表示 $u\to v$ 上最短路的点集,于是有状态转移方程
$$ \text{path}(i,j)=\bigcup_{\text{dis}(i,k)+w(k,j)=\text{dis}(i,j)}\text{path}(i,k) $$
对固定的 $i$,考虑将 $j$ 按 $\text{dis}(i,j)$ 从小到大排序后用 $\text{bitset}$ 加速上述转移。
然后按 $1\sim n$ 顺序枚举 $j$,于是有 $\text{ok}(i,j)=\sum_{k=1}^n ok(i,k)\And ok(k,j)\And (k\in \text{path}(i,j))$。
用两种 $\text{bitset}$ 维护 $\text{ok}(i,\ast),\text{ok}(\ast,i)$,上述转移也可以用 $\text{bitset}$ 加速。总时间复杂度 $O\left(nm\log m+\frac {n^2m}w\right)$。