思路:
考虑到倒着插入,原问题就变成了一个三维偏序问题,我们首先对插入时间
t
进行排序,然后对
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 100010;
int n, m, c[maxn], match[maxn], ans[maxn];
ll res;
struct node{
int x, y, t;
bool flag;
}a[maxn], b[maxn];
bool cmpx(node a, node b){if(a.x == b.x) return a.y < b.y; return a.x < b.x;}
bool cmpt(node a, node b){return a.t < b.t;}
void add(int x, int v){while(x <= n) c[x] += v, x += (x&(-x));}
int que(int x){int res = 0; while(x) res += c[x], x -= (x&(-x)); return res;}
void cdq(int l, int r){
if(l == r) return;
int mid = (l+r)>>1, sz = r-l+1, cnt = 0;
for(int i = l; i <= mid; i ++) b[++ cnt] = a[i], b[cnt].flag = 0;
for(int i = mid+1; i <= r; i ++) b[++ cnt] = a[i], b[cnt].flag = 1;
sort(b+1, b+cnt+1, cmpx);
for(int i = 1; i <= sz; i ++){
if(b[i].flag == 0) add(b[i].y, 1);
else ans[b[i].t] += que(n) - que(b[i].y);
}
for(int i = 1; i <= sz; i ++) if(b[i].flag == 0) add(b[i].y, -1);
for(int i = sz; i >= 1; i --){
if(b[i].flag == 0) add(b[i].y, 1);
else ans[b[i].t] += que(b[i].y);
}
for(int i = sz; i >= 1; i --) if(b[i].flag == 0) add(b[i].y, -1);
cdq(l, mid); cdq(mid+1, r);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++){
a[i].x = i;
scanf("%d", &a[i].y);
match[a[i].y] = i;
}
int cc = n, x;
for(int i = 1; i <= m; i ++){
scanf("%d", &x);
a[match[x]].t = cc --;
}
for(int i = 1; i <= n; i ++){
if(a[i].t == 0) a[i].t = cc --;
}
sort(a+1, a+1+n, cmpt);
cdq(1, n);
for(int i = 1; i <= n; i ++) res += ans[i];
for(int i = n; i > n-m; i --){
printf("%lld\n", res);
res -= ans[i];
}
return 0;
}