树状数组套线段树
1 #include<cstdio> 2 #define ll long long 3 #define R register 4 using namespace std; 5 const int N=100005,M=N*100; 6 int n,m,a[N],pos[N]; 7 int lc[M],rc[M],tot; 8 int sum[M]; 9 int bit[N]; 10 inline int read(){ 11 int x=0,w=1;char c=0; 12 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();} 13 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar(); 14 return x*w; 15 } 16 void seg_modify(int& k,int l,int r,int pos,int x){ 17 if(!k) k=++tot; 18 sum[k]+=x; 19 if(l==r) return; 20 int mid=(l+r)>>1; 21 if(pos<=mid) seg_modify(lc[k],l,mid,pos,x); 22 else seg_modify(rc[k],mid+1,r,pos,x); 23 return; 24 } 25 ll seg_quelower(int k,int l,int r,int v){ 26 if(!k) return 0; 27 if(l==r) return sum[k]; 28 int mid=(l+r)>>1; 29 if(v<=mid) return seg_quelower(lc[k],l,mid,v); 30 else return (ll)sum[lc[k]]+seg_quelower(rc[k],mid+1,r,v); 31 } 32 ll seg_queupper(int k,int l,int r,int v){ 33 if(!k) return 0; 34 if(l==r) return sum[k]; 35 int mid=(l+r)>>1; 36 if(v<=mid) return (ll)sum[rc[k]]+seg_queupper(lc[k],l,mid,v); 37 else return seg_queupper(rc[k],mid+1,r,v); 38 } 39 inline int lowbit(int k){return k&(-k);} 40 inline void bit_modify(int pos,int v,int x){ 41 while(pos<=n){ 42 seg_modify(bit[pos],1,n,v,x); 43 pos+=lowbit(pos); 44 } 45 return; 46 } 47 inline ll bit_que(int pos,int v,bool b){ 48 ll ans=0; 49 while(pos){ 50 ans+=b?seg_queupper(bit[pos],1,n,v):seg_quelower(bit[pos],1,n,v); 51 pos-=lowbit(pos); 52 } 53 return ans; 54 } 55 int main(){ 56 int t1,t2; 57 n=read(),m=read(); 58 for(R int i=1;i<=n;i++){ 59 a[i]=read(),pos[a[i]]=i; 60 bit_modify(i,a[i],1); 61 } 62 ll ans=0; 63 for(R int i=1;i<=n;i++) ans+=bit_que(i-1,a[i]+1,1); 64 for(R int i=1;i<=m;i++){ 65 t1=read();t2=pos[t1]; 66 printf("%lld ",ans); 67 ans-=bit_que(t2-1,t1+1,1); 68 ans-=bit_que(n,t1-1,0)-bit_que(t2,t1-1,0); 69 bit_modify(t2,t1,-1); 70 } 71 72 }