每次删一个数,询问逆序对数量
分块大法好,暴力出奇迹
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 100010
#define Size 500
using namespace std;
void read(int &num){
num = 0;char ch = getchar();
for(; ch < '!'; ch = getchar());
for(; ch > '!'; ch = getchar())
num = num * 10 + ch - 48;
}
int n, m;
int t[maxn], pos[maxn], here[maxn];
bool bo[maxn];
const int inf = 0x7fffffff;
struct block{
int a[Size], sum, l, r, cnt;
void build(int id){
cnt = 0;
for(int i = l; i <= r; i ++){
a[++ cnt] = t[i];
pos[i] = id;
here[t[i]] = id;
}
sort(a + 1, a + 1 + cnt);
}
void rebuild(int p){
for(int i = 1; i <= cnt; i ++)
if(a[i] == p){
a[i] = inf;
break;
}
sort(a + 1, a + 1 + cnt);
cnt --;bo[p] = true;
}
int small(int p){
if(cnt == 0)return 0;
int t = lower_bound(a + 1, a + 1 + cnt, p) - a;
if(a[t] > p)t --;
if(t > cnt)return cnt;
return t;
}
int big(int p){
if(cnt == 0)return 0;
int t = lower_bound(a + 1, a + 1 + cnt, p) - a;
if(a[t] > p)t --;
if(t == 0)return cnt;
if(t > cnt)return 0;
return cnt - t;
}
int bruteforce(int p){
int flag = true;
int ret = 0;
for(int i = l; i <= r; i ++){
if(bo[t[i]])continue;
if(t[i] == p){flag = false;continue;}
if(flag && t[i] > p)ret ++;
if(!flag && t[i] < p)ret ++;
}
return ret;
}
}b[Size];
struct BIT{
int t[maxn];
int lowbit(int i){
return i & -i;
}
void update(int pos, int val){
for(int i = pos; i; i -= lowbit(i))
t[i] += val;
}
int ask(int pos){
int ret = 0;
for(int i = pos; i <= n; i += lowbit(i))
ret += t[i];
return ret;
}
}T;
long long getanti(){
long long ans = 0;
for(int i = 1; i <= n; i ++){
ans += T.ask(t[i]);
T.update(t[i], 1);
}
return ans;
}
int main(){
read(n), read(m);
for(int i = 1; i <= n; i ++)
read(t[i]);
int blo = sqrt(n);
if(blo * blo < n)blo ++;
for(int i = 1; i <= blo; i ++){
int L = (i - 1) * blo + 1, R = i * blo;
R = min(R, n);
b[i].l = L, b[i].r = R;
b[i].build(i);
if(R == n){
blo = i;
break;
}
}
long long ans = getanti();
int x;
for(int i = 1; i <= m; i ++){
printf("%lld\n", ans);
read(x);
int t = here[x];
ans -= b[t].bruteforce(x);
for(int j = 1; j < t; j ++)
ans -= b[j].big(x);
for(int j = t + 1; j <= blo; j ++)
ans -= b[j].small(x);
b[t].rebuild(x);
}
return 0;
}