传送门:bzoj3295
题解
线段树套树状数组
代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int M=5e6+10;
int n,m,tag[N],t[N];
int vis[N],i,j,tot=1,cnt,a[N],b[N];
int tre[N],q,sz[M],rt[M],ch[M][2];
int u[33],v[33],uu,vv;
ll ori,sum;
inline int rd()
{
char ch=getchar();int x=0,f=1;
while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
inline void add(int x)
{
for(int i=x;i<=n;i+=i&(-i)) tre[i]++;
}
inline int get(int x)
{
int ret=0;
for(int i=x;i;i-=i&(-i)) ret+=tre[i];
return ret;
}
inline void update(int &k,int l,int r,int pos)
{
if(!k) k=++cnt;
sz[k]++;
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) update(ch[k][0],l,mid,pos);
else update(ch[k][1],mid+1,r,pos);
}
inline int gel(int L,int R,int val)
{
uu=vv=0;L--;int ans=0;
for(i=L;i;i-=i&(-i)) u[++uu]=rt[i];
for(i=R;i;i-=i&(-i)) v[++vv]=rt[i];
int l=1,r=n,mid;
while(l<r){
mid=(l+r)>>1;
if(val<=mid){
for(i=1;i<=uu;i++) {ans-=sz[ch[u[i]][1]];u[i]=ch[u[i]][0];}
for(i=1;i<=vv;i++) {ans+=sz[ch[v[i]][1]];v[i]=ch[v[i]][0];}
r=mid;
}else{
for(i=1;i<=uu;i++) u[i]=ch[u[i]][1];
for(i=1;i<=vv;i++) v[i]=ch[v[i]][1];
l=mid+1;
}
}
return ans;
}
inline int ger(int L,int R,int val)
{
uu=vv=0;L--;int ans=0;
for(i=L;i;i-=i&(-i)) u[++uu]=rt[i];
for(i=R;i;i-=i&(-i)) v[++vv]=rt[i];
int l=1,r=n,mid;
while(l<r){
mid=(l+r)>>1;
if(val>mid){
for(i=1;i<=uu;i++) {ans-=sz[ch[u[i]][0]];u[i]=ch[u[i]][1];}
for(i=1;i<=vv;i++) {ans+=sz[ch[v[i]][0]];v[i]=ch[v[i]][1];}
l=mid+1;
}else{
for(i=1;i<=uu;i++) u[i]=ch[u[i]][0];
for(i=1;i<=vv;i++) v[i]=ch[v[i]][0];
r=mid;
}
}
return ans;
}
int main(){
n=rd();m=rd();
for(i=1;i<=n;i++) {
tag[i]=rd();t[tag[i]]=i;
}
for(i=1;i<=n;i++){a[i]=get(n)-get(tag[i]);sum+=a[i];add(tag[i]);}
memset(tre,0,sizeof(tre));
for(i=n;i>=1;i--){b[i]=get(tag[i]-1);add(tag[i]);}
while(m--){
q=rd();
printf("%lld\n",sum);
sum-=(a[t[q]]+b[t[q]]);
if(t[q]>1) sum+=gel(1,t[q]-1,q);
if(t[q]<n) sum+=ger(t[q]+1,n,q);
for(i=t[q];i<=n;i+=i&(-i)) update(rt[i],1,n,q);
}
return 0;
}