# [BZOJ3295][Cqoi2011]动态逆序对（分块重建）

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define erp(i,a,b) for(int i=a;i>=b;--i)
#define LL long long
using namespace std;
const int MAXN = 100005;
int a[MAXN], pos[MAXN], N, M, bsz, b[MAXN], cnt, c[MAXN], r;
inline void add(int i,int x) { for(;i<=N;i+=i&-i) c[i]+=x; }
inline int qsum(int i) { for(r=0;i;i^=i&-i) r+=c[i]; return r; }
LL val[MAXN];
struct qua{
int p,id;
bool operator<(const qua&b)const{return p<b.p;}
}q[MAXN];
int main()
{
scanf("%d%d",&N,&M);
rep(i,1,N) scanf("%d",a+i),pos[a[i]]=i;
bsz = ceil(sqrt(M+0.5))+0.1; bsz<<=1;
if (bsz>M) bsz = M;
rep(i,1,M) scanf("%d",b+i);
LL tot = 0;
for (int i=1, nex, p; i<=M; i+=bsz)
{
cnt = 0;
nex = min(M, i+bsz-1);
rep(j, i, nex) q[++cnt]=(qua){pos[b[j]],j};
sort(q+1,q+cnt+1);
p = 1;
int num = 0;
rep(j,0,N) c[j]=0;
rep(j, 1, N)
{
if (p>cnt) break;
if (a[j]<0) continue;
if (j==q[p].p) val[q[p].id]+=num-qsum(a[j]), p++;
}
p = cnt;
rep(j,0,N) c[j]=0;
erp(j, N, 1)
{
if (p<1) break;
if (a[j]<0) continue;
if (j==q[p].p) val[q[p].id]+=qsum(a[j]), p--;
}
rep(j, i, nex)
{
rep(k, i, j-1) if (pos[b[k]]<pos[b[j]]&&b[k]>b[j]||pos[b[k]]>pos[b[j]]&&b[k]<b[j]) val[j]--;
printf("%lld\n", tot); tot -= val[j];
}
rep(j, i, nex) a[pos[b[j]]]=-1;
}
return 0;
}


#### 归并排序求逆序对

2013-11-20 21:11:38

#### 算法--逆序对

2015-03-08 20:39:45

#### BZOJ 2957 楼房重建 (分块)

2016-10-10 18:36:29

#### n根号n解决在线无修区间逆序对问题

2017-09-14 17:04:43

#### 20.剑指offer-数组中的逆序对

2017-05-15 13:45:49

#### 逆序对

2017-12-03 21:28:20

#### C++计算逆序对

2017-08-25 13:10:54

#### 求逆序对

2011-10-08 14:09:59

#### 【bzoj3295】[Cqoi2011]动态逆序对 树状数组套主席树

2016-04-05 21:57:59

#### [BZOJ3295] [Cqoi2011]动态逆序对 (树套树)or(CDQ分治)

2016-01-23 22:16:17