序列分块套值域分块,O(n),有#define int long long,printf全部检查过,下标从0开始。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N(1e5),B(310),K{N/B+1};
int a[N+5];
int vb[B<<1][B<<1],v[B<<1][N+5];
int L[B<<1],R[B<<1],up;
int ppip(int l,int r,int v)
{
int ans{0};
for (int i{l};i<=r;++i)
ans+=(a[i]!=-1&&a[i]<v);
return ans;
}
int n;
int query(int l,int r,int k)
{
if (l>r) return 0;
if (l/K==r/K||l/K==r/K-1) return ppip(l,r,k);
int ans{ppip(l,R[l/K],k)+ppip(L[r/K],r,k)};
for (int i{0};i<k/K;++i)
ans+=vb[r/K-1][i]-vb[l/K][i];
for (int i{k/K*K};i<k;++i)
ans+=v[r/K-1][i]-v[l/K][i];
return ans;
}
int ppap(int l,int r,int v)
{
int ans{0};
for (int i{l};i<=r;++i)
ans+=(a[i]!=-1&&a[i]>v);
return ans;
}
int puery(int l,int r,int k)
{
if (l>r) return 0;
if (l/K==r/K||l/K==r/K-1) return ppap(l,r,k);
int ans{ppap(l,R[l/K],k)+ppap(L[r/K],r,k)};
for (int i{up};i>k/K;--i)
ans+=vb[r/K-1][i]-vb[l/K][i];
for (int i{k/K*K+K-1};i>k;--i)
ans+=v[r/K-1][i]-v[l/K][i];
return ans;
}
signed main()
{
int m;
cin>>n>>m;
for (int i{0};i<n;++i)
{
int z;scanf("%lld",&z);
a[z-1]=i;
}
up={(n-1)/K};
for (int i{0};i<=(n-1)/K;++i)
L[i]=i*K,R[i]=(i+1)*K-1;
R[(n-1)/K]=n-1;
for (int i{0};i<n;++i)
{
++vb[i/K][a[i]/K];
++v[i/K][a[i]];
}
for (int i{1};i<=up;++i)
{
for (int j{0};j<B;++j) vb[i][j]+=vb[i-1][j];
for (int j{0};j<n;++j) v[i][j]+=v[i-1][j];
}
int nt{0};
for (int i{0};i<n;++i)
nt+=query(i+1,n-1,a[i]);
// cout<<nt<<endl;
// return 0;
while (m--)
{
int z;scanf("%lld",&z);--z;
printf("%lld\n",nt);
nt-=query(z+1,n-1,a[z])+puery(0,z-1,a[z]);
for (int j{z/K};j<=up;++j)
{
--vb[j][a[z]/K];
--v[j][a[z]];
}
a[z]=-1;
}
return 0;
}