输出的答案有负数。
以下标为第一维,权值为 cdq 排序的那一维,删除时间为统计答案的那一维。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n , m;
struct Point
{
int val , t;
}a[N] , tmp[N] , b[N];
int pos[N];
int ans[N];
int tr[N];
inline int lowbit (int x)
{
return x&-x;
}
inline void add (int x , int val)
{
for (int i=x ; i<=n ; i+=lowbit(i))
{
tr[i] += val;
}
}
inline int query (int x)
{
if (!x) return 0;//可能传0进来
int res = 0;
for (int i=x ; i ; i-=lowbit(i))
{
res += tr[i];
}
return res;
}
void cdq1 (int l , int r)
{
if(l>=r) return;
int mid = (l+r)>>1;
cdq1(l , mid) , cdq1(mid+1 , r);
int i=mid , j=r , k=r;
while (i>=l && j>mid)//维护一个递减的序列
{
if (a[i].val>a[j].val)
{
tmp[k--] = a[j];
add(a[j].t , 1);
j--;
}
else //找到第一个i<j的地方统计i的答案
{
tmp[k--] = a[i];
ans[a[i].t] += query(n)-query(a[i].t-1);
i--;
}
}
while (i>=l)
{
ans[a[i].t] += query(n)-query(a[i].t-1);
tmp[k--] = a[i--];
}
while (j>mid)
{
tmp[k--] = a[j--];
}
for (int i=l ; i<=mid ; i++)
{
a[i] = tmp[i];
}
for (int i=mid+1 ; i<=r ; i++)
{
add(a[i].t , -1);
a[i] = tmp[i];
}
}
void cdq2 (int l , int r)
{
if (l>=r) return;
int mid = (l+r)>>1;
cdq2(l , mid) , cdq2(mid+1 , r);
int i = l , j = mid+1 , k = l;
while (i<=mid && j<=r)
{
if (a[i].val>a[j].val)//维护一个升序的序列
{
add(a[i].t , 1);
tmp[k++] = a[i++];
}
else //找到第一个i<j的地方统计j的答案
{
ans[a[j].t] = query(n)-query(a[j].t-1);
tmp[k++] = a[j++];
}
}
while (i<=mid)
{
tmp[k++] = a[i++];
}
while (j<=r)
{
ans[a[j].t] += query(n)-query(a[j].t-1);
tmp[k++] = a[j++];
}
for (int i=l ; i<=mid ; i++)
{
add(a[i].t , -1) , a[i] = tmp[i];
}
for (int i=mid+1 ; i<=r ; i++)
{
a[i] = tmp[i];
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n >> m;
for (int i=1 ; i<=n ; i++)
{
cin >> a[i].val;
pos[a[i].val] = i;
}
for (int i=1 ; i<=m ; i++)
{
int x;
cin >> x;
a[pos[x]].t = i;
}
for (int i=1 , j=m+1 ; i<=n ; i++)
{
if (!a[i].t)
{
a[i].t = j;//时间不一样的话不方便统计,全赋成一个值
}
}
for (int i=1 ; i<=n ; i++) b[i] = a[i];
cdq1(1 , n);
for (int i=1 ; i<=n ; i++) a[i] = b[i];
cdq2(1 , n);
for (int i=1 ; i<=m ; i++)
{
cout << ans[i] << '\n';
}
return 0;
}