发现每删除一个数, 对答案的贡献是前面大于它的和后面小于它的, 加上一个单点修改, 写一个树套数就可以了
#include<bits/stdc++.h>
#define N 100050
#define LL long long
using namespace std;
int read(){
int cnt=0; char ch=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();
return cnt;
}
int n,m,id[N],rt[N],tot; LL ans;
struct Node{int ls,rs,val;}t[N*400];
void Insert(int &x,int l,int r,int pos,int val){
if(!x) x = ++tot; t[x].val+=val;
if(l==r) return;
int mid = (l+r) >> 1;
if(pos<=mid) Insert(t[x].ls, l, mid, pos, val);
else Insert(t[x].rs, mid+1, r, pos, val);
}
int Quary(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return (LL)t[x].val;
int mid = (l+r) >> 1; LL ans = 0;
if(L<=mid) ans += Quary(t[x].ls, l, mid, L, R);
if(R>mid) ans += Quary(t[x].rs, mid+1, r, L, R);
return ans;
}
void add(int x,int val,int k){for(;x<=n;x+=x&-x) Insert(rt[x],1,n,val,k);}
LL qu(int x,int L,int R){LL ans=0; for(;x;x-=x&-x) ans+=Quary(rt[x],1,n,L,R); return ans;}
LL Qu(int l,int r,int L,int R){if(l>r||L>R) return 0; return qu(r, L, R) - qu(l-1, L, R);}
int main(){
n = read(); m = read();
for(int i=1;i<=n;i++){
int x = read(); id[x] = i;
add(i,x,1); ans += Qu(1,i-1,x+1,n);
}
while(m--){
printf("%lld\n",ans);
int x = read(), pos = id[x];
ans -= Qu(1,pos-1,x+1,n);
ans -= Qu(pos+1,n,1,x-1);
add(pos,x,-1);
} return 0;
}