Description
Solution
算法一
考虑一个 O ( n q ) O(nq) O(nq) 的算法。
我们动态地维护序列 a a a,其中 a i a_i ai 表示 p i p_i pi 是 [ 1 , i ] [1,i] [1,i] 中第几小的。显然,有 a i = i − b i a_i=i-b_i ai=i−bi。
对于一次修改,直接 O ( 1 ) O(1) O(1) 地更新 a i a_i ai。
对于一次查询,令 a n s = a i ans=a_i ans=ai,并从 i + 1 i+1 i+1 一直扫描到 n n n。若当前的 a n s ans ans 满足 a n s ≥ a j ans \ge a_j ans≥aj,那么就将 a n s ans ans 加上 1 1 1,否则不做操作。这里加 1 1 1 的实质是,由于 j > i j>i j>i 且 p j p_j pj 在 [ 1 , j ] [1,j] [1,j] 中从小到大的排名比 [ 1 , j − 1 ] [1,j-1] [1,j−1] 中 p i p_i pi 的排名要高,所以 p j < p i p_j<p_i pj<pi;此时,我们在 [ 1 , j − 1 ] [1,j-1] [1,j−1] 的排名列表中在 i i i 之前插入了一个位置,需将 a n s ans ans 加上 1 1 1 表示 i i i 在 [ 1 , j ] [1,j] [1,j] 中的排名。
ans=a[i];
for (int j=i+1;j<=n;j++)
if (ans>=a[j]) ans++;
最后输出 a n s ans ans 即可。
算法二
看到时限为 5.00s \text{5.00s} 5.00s 且 n , q ≤ 1 0 5 n,q \le 10^5 n,q≤105,根据 Codeforces \text{Codeforces} Codeforces 的做题经验,这显然是一道分块题(或者是一道树套树)。
考虑分块,令块长为 B B B。
对于每一个块,我们维护出一个列表 v v v。其实际意义是,若进入这个块时 a n s = x ans=x ans=x,那么最终从这个块出来时 a n s = v x + x ans=v_x+x ans=vx+x。
每次修改都是单点的,我们更新 a i a_i ai 并重构该块的列表 v v v。
对于第一次查询,我们从左往右扫描,对于零散块直接在 a a a 中扫描并更新 a n s ans ans,对于整块直接调用列表更新 a n s ans ans。
显然,每次查询都是 O ( B + n B ) O(B+\frac n B) O(B+Bn) 的。关键在于,如何快速重构某一块的列表。
为方便叙述,令该块为 [ L , R ] [L,R] [L,R]。考虑从前往后扫描,实时维护一个数据结构,里面存储了若干个三元组 ( l , r , c ) (l,r,c) (l,r,c),表示将 v ∈ [ l , r ] v \in [l,r] v∈[l,r] 从块头推到当前位置时的值 v + c v+c v+c。每次更新的时候,我们通过二分找到 set \text{set} set 里面第一个满足 L ≤ a i L \le a_i L≤ai 的位置,并将该处的 ( l , r , c ) (l,r,c) (l,r,c) 段成 ( l , L − 1 , c ) (l,L-1,c) (l,L−1,c) 与 ( L , R , c + 1 ) (L,R,c+1) (L,R,c+1),将后者向后面一个 ( l , r , c ) (l,r,c) (l,r,c) 合并。接着,对于该位置往后的那一段后缀,将 c c c 全部加一。显然,这个数据结构需要维护单点查询,单点插入与区间加,采用平衡树即可。由于最多有 log n \log n logn 个区间,所以单次重构是 O ( B log B ) O(B \log B) O(BlogB) 的。
总复杂度 O ( q ( B + n B + B log B ) ) O(q(B+\frac n B+ B \log B)) O(q(B+Bn+BlogB))。当 n = 1 0 5 , q = 1 0 5 n=10^5,q=10^5 n=105,q=105 时,取 B = 120 B=120 B=120 理论最优,实际应将 B B B 调小(平衡树的常数很大)。
值得一提的是,若不维护若干个三元组,而用线段树维护长度为 n n n 的序列,那么复杂度就是 O ( q ( B + n B + B log n ) ) O(q(B+\frac n B+B \log n)) O(q(B+Bn+Blogn)),理论劣于上面的解法。但是,线段树常数较小,所以其实二者差不太多。