The topic requirements can be converted into a query within a range of how many are larger (or smaller) than Val.
Interval is decomposed by Segment tree (LOGN), and each interval maintains a rank tree.
Rank can be queried by bit, but in order to ensure that bits in different intervals are separated from each other.
First divide and conquer, divide and conquer the sorting to complete discretization and calculate the order of each element and other elements to preserve the reverse of the composition of iv[i].
The initial value sums all IV, one pair is counted two times so divided by two.
Each time you delete the element Val subtracts the inverse of the Val corresponding pair.
Minus Iv[val], but subtracting the inverse pairs of elements that were previously deleted (these reverse pairs have been counted once).
So add the deleted elements to the line tree.
After subtracting the current Iv[val], the query and add the current element Val and the previous position and the following position constitute the inverse pair.
Complexity of
O (Nlogn) pretreatment, O (m*logn*logn) answer
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5, LogN = 20;
typedef long long ll;
Ll invPair;
int a[maxn],p[maxn];
int iv[maxn];
Int n;
int s[maxn<<2];
int C[LogN][maxn];
int Set[LogN][maxn];
#define para int o = 1, int l = 1,int r = n,int dep = 0
#define lo (o<<1)
#define ro (o<<1|1)
#define TEMP int mid = (l+r)>>1, lc = lo, rc = ro;
#define lsn lc, l, mid, dep+1
#define rsn rc, mid+1, r, dep+1
#define lb(x) ((x)&-(x))
int sum(int C[],int x)
{
Int re = 0;
While (x>0) {
Re + = C[x];
X = lb (x);
}
Return re;
}
void add(int C[],int x,int d,int r)
{
While (x<=r) {
C[x] + = D;
X + = lb (x);
}
}
Int QPOs;
int ql,qr,val;
void queryPrefix(para)
{
if(1<=l&&r<=qr){
Int POS = upper_bound (set [dep] + L, set [dep] + R + 1, Val) - set [dep] - L; / / equal to the number of the largest element equal to val
Invpair + = s [O] - sum (C [dep] + L-1, POS); / / get the number of elements greater than val
}else {
TEMP
queryPrefix(lsn);
if(qr>mid) queryPrefix(rsn);
}
}
void querySuffix(para)
{
if(ql<=l&&r<=n){
Int POS = lower_bound (set [dep] + L, set [dep] + R + 1, Val) - set [dep] - L; / / the number of elements strictly less than val
invPair += sum(C[dep]+l-1,pos);
}else {
TEMP
if(ql<=mid) querySuffix(lsn);
querySuffix(rsn);
}
}
void modify(para)
{
S[o]++;
If (L = = R) {
C[dep][l] = 1;
}else{
TEMP
if(qpos<=mid) modify(lsn);
else modify(rsn);
Int POS = upper_bound (set [dep] + L, set [dep] + R + 1, Val) - set [dep] - L; / / Val is in set, numbered from 1
Add (C [dep] + L-1, POS, 1, R-L + 1); / / L-1 is position 0, containing R-L + 1 elements
}
}
//In order to ensure that bits do not affect each other, merge ﹣ sort is discrete and the reverse order pair is calculated at the same time
void discretize(para)
{
S[o] = 0;
memset(C[dep]+l,0,sizeof(int)*(r-l+1));
If (L = = R) {
Set[dep][l] = a[l];
Return;
}else {
TEMP;
discretize(lsn);
discretize(rsn);
int p = l, q = mid+1, k = l;
while(p<=mid || q<=r){
if(q > r|| (p <= mid && Set[dep+1][p] <= Set[dep+1][q]) ){
IV [set [dep + 1] [P]] + = k-p; / / and the following numbers form a reverse order pair
Set[dep][k++] = Set[dep+1][p++];
}else {
IV [set [dep + 1] [q] + = mid-P + 1; / / opposite the previous number
Set[dep][k++] = Set[dep+1][q++];
}
}
}
}
//#define LOCAL
Int main ()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
Int m;
while(~scanf("%d%d",&n,&m)){
memset(iv+1,0,sizeof(int)*n);
for(int i = 1; i <= n; i++){
scanf("%d",a+i);
P[a[i]] = I;
}
InvPair = 0;
discretize();
for(int i = 1; i <= n; i++){
invPair += iv[i];
}
invPair >>= 1;
While (m--) {
scanf("%d",&val);
printf("%lld\n",invPair);
invPair -= iv[val];
qr = p[val]-1;
ql = p[val]+1;
if(qr>=1) queryPrefix();
if(ql<=n) querySuffix();
qpos = p[val];
Modify ();
}
}
Return 0;
}
UVA 11990 ' Dynamic ' inversion