传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5808
题意:
给出一个数列,每次都会删去一个数并将原数列分为两段,问每次删数前所有段中逆序对的最大数量,强制在线。
思路:
利用主席树可以每次O(log(n))算出一个点在某个区间的逆序对数量,一开始还没删的时候先统计总共有多少逆序对。
对于每次删除操作,都暴力算出拆分后小区间的逆序对,大区间逆序对再根据小区间来算。
以左边为小区间为例: del 将要被删除的点,tot 原先该区间的逆序对数。
①利用主席树暴力算左区间内部有多少逆序对 lcnt 。
②计算左区间中每个值和 ( del + 右区间 ) 的逆序对数量之和,也就是对于左区间中的点来说原先跨区间的逆序对数量和 temp 。
③计算 del 与右区间的逆序对数量 dcnt 。
④剩下左区间的逆序对数量即为 lcnt ,右区间逆序对数量为 tot - lcnt - temp - dcnt 。
如果右边为小区间也类似计算就可以了。
答案值可以用multiset来维护,已经删除的位置可以用set保存,每个区间的逆序对数可以用map来保存。
AC代码:
#include<iostream>
#include<cstdio>