题意:给一个1-n的排列,按照某种顺序一些数(其他数顺序不变),输出每次删除之前逆序对的数目。
分析:线段树每个节点表示的一段数字排序,每个节点用树状数组维护删除的点。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 1000000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int maxn=200005;
int n,m;
int order[30][maxn];
int tree[30][maxn];
int pos[maxn];
ll ans;
int lowbit(int x)
{
return x&-x;
}
int getSum(int* s,int x,int o)
{
int sum=0;
while(x>o) {
sum+=s[x];
x-=lowbit(x);
}
return sum;
}
void update(int* s,int v,int x,int o)
{
while(x<=o) {
s[x]+=v;
x+=lowbit(x);
}
}
void build(int l,int r,int rt,int d)
{
for(int i=l;i<=r;i++) {
order[d][i]=order[d-1][i];
tree[d][i]=0;
}
if(l==r) return;
int m=(l+r)/2;
build(l,m,rt<<1,d+1);
build(m+1,r,rt<<1|1,d+1);
sort(order[d]+l,order[d]+r+1);
}
void query(int l,int r,int x,int flag,int d,int L,int R,int rt)
{
if(l>r)
return;
if(l<=L&&r>=R) {
int k=lower_bound(order[d]+L,order[d]+R+1,x)-order[d];
if(k>R||order[d][k]>x) {
k--;
}
int u=getSum(tree[d],k,L-1);
if(flag) {
k=k-L+1;
ans-=k-u;
}
else {
int v=getSum(tree[d],R,L-1);
v-=u;
ans-=R-k-v;
}
return;
}
int m=(L+R)/2;
if(l<=m){
query(l,r,x,flag,d+1,L,m,rt<<1);
}
if(r>m) {
query(l,r,x,flag,d+1,m+1,R,rt<<1|1);
}
}
void Update(int l,int x,int d,int L,int R,int rt)
{
if(l==L&&l==R) {
update(tree[d],1,l,R);
return;
}
int m=(L+R)/2;
if(l<=m) {
Update(l,x,d+1,L,m,rt<<1);
}
else {
Update(l,x,d+1,m+1,R,rt<<1|1);
}
int k=lower_bound(order[d]+L,order[d]+R+1,x)-order[d];
update(tree[d],1,k,R);
}
int main()
{
int x;
while(~scanf("%d%d",&n,&m)) {
memset(tree[0],0,sizeof(tree[0]));
ans=0;
for(int i=1;i<=n;i++) {
scanf("%d",&order[0][i]);
pos[order[0][i]]=i;
ans+=i-1-getSum(tree[0],order[0][i],0);
update(tree[0],1,order[0][i],n);
}
build(1,n,1,1);
for(int i=0;i<m;i++) {
scanf("%d",&x);
printf("%lld\n",ans);
query(1,pos[x]-1,x,0,1,1,n,1);
query(pos[x]+1,n,x,1,1,1,n,1);
Update(pos[x],x,1,1,n,1);
}
}
return 0;
}