题目:对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。
思路:如果倒着看的话,就变成了插入操作,第一个删除的数使最后一个插入的数,我们用<x,y,t>来表示每个插入操作,x表示插入位置,y表示插入的数,t表示插入的时间,对时间进行二分操作,每次保证左边区间的时间都小于右边区间的时间,并且每个区间的x都是递增的
_left[i]表示第i次操作后,和左边的数新构成的逆序对的对数
_right[i]表示第i次操作后,和右边的数新构成的逆序对的对数
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<numeric>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define INF 0x3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define PP puts("*********************");
template<class T> T f_abs(T a){ return a > 0 ? a : -a; }
template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
// 0x3f3f3f3f3f3f3f3f
//0x3f3f3f3f
const int maxn=1e5+50;
struct Node{
int x,y,t;
}q[maxn],q1[maxn],q2[maxn];
struct BIT{
int n,b[maxn];
void init(int _n){
n=_n;
mm(b,0);
}
void add(int i,int val){
for(;i<=n;i+=i&(-i))
b[i]+=val;
}
int sum(int i){
int ret=0;
for(;i>0;i-=i&(-i))
ret+=b[i];
return ret;
}
}bit;
int pos[maxn];
LL ans[maxn];
int _left[maxn],_right[maxn];
int n,m;
void cdq(int L,int R){
if(L>=R) return;
int sz1=0,sz2=0;
int mid=(L+R)>>1;
for(int i=L;i<=R;i++){
if(q[i].t<=mid) q1[sz1++]=q[i];
else q2[sz2++]=q[i];
}
int j=0;
for(int i=0;i<sz2;i++){
for(;j<sz1&&q1[j].x<q2[i].x;j++)
bit.add(q1[j].y,1);
_left[q2[i].t]+=bit.sum(n)-bit.sum(q2[i].y);
}
for(int i=0;i<j;i++)
bit.add(q1[i].y,-1);
j=sz1-1;
for(int i=sz2-1;i>=0;i--){
for(;j>=0&&q1[j].x>q2[i].x;j--)
bit.add(q1[j].y,1);
_right[q2[i].t]+=bit.sum(q2[i].y-1);
}
for(int i=sz1-1;i>j;i--)
bit.add(q1[i].y,-1);
memcpy(q+L,q1,sz1*sizeof(Node));
memcpy(q+L+sz1,q2,sz2*sizeof(Node));
cdq(L,mid);
cdq(mid+1,R);
}
int main(){
// freopen("D:\\input.txt","r",stdin);
// freopen("D:\\output.txt","w",stdout);
int x;
while(~scanf("%d%d",&n,&m)){
bit.init(n);
for(int i=1;i<=n;i++){
scanf("%d",&q[i].y);
q[i].x=i;q[i].t=0;
pos[q[i].y]=i;
ans[i]=_left[i]=_right[i]=0;
}
int tim=n;
for(int i=1;i<=m;i++){
scanf("%d",&x);
q[pos[x]].t=tim--;
}
for(int i=1;i<=n;i++)
if(q[i].t==0)
q[i].t=tim--;
// PP;
// for(int i=1;i<=n;i++)
// printf("%d %d %d\n",q[i].x,q[i].y,q[i].t);
cdq(1,n);
ans[0]=_left[0]=_right[0]=0;
for(int i=1;i<=n;i++)
ans[i]=ans[i-1]+_left[i]+_right[i];
for(int i=n;i>n-m;i--)
printf("%lld\n",ans[i]);
// PP;
// for(int i=1;i<=n;i++)
// printf("%d %d %d\n",i,_left[i],_right[i]);
// for(int i=1;i<=n;i++)
// printf("%d ",bit.b[i]);
}
return 0;
}