传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3295
用树状数组套平衡树统计逆序对,每加入一个数就统计在它前面比他大+在他后面比他大,可以离线,逆序加入数字,可以更快一点,
PS:线段树常数真心不能看……
Code:
#include<cstdio>
#include<climits>
#include<iostream>
#include<algorithm>
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define L i<<1
#define R i<<1|1
using namespace std;
const int maxn=1e5+10;
const int maxm=50010;
int n,m;
int a[maxn],b[maxm];
bool hash[maxn];
int rnd(){
static int KEY=12345678;
return KEY+=KEY<<2|1;
}
int getint(){
int res=0,ok=0;char ch;
while(1){
ch=getchar();
if(ch<='9'&&ch>='0'){
res*=10;res+=ch-'0';ok=1;
}else if(ok)break;
}return res;
}
struct Treap{
struct node{
int val,key;
int size;
node *c[2];
node(int _val,node *C){
val=_val;key=rnd();
c[0]=c[1]=C;size=1;
}
void rz(){
size=c[0]->size+c[1]->size+1;
}
};
node *root,*Null;
Treap(){
Null=new node(0,0);
Null->size=0;Null->c[0]=Null->c[1]=Null;
Null->key=INT_MAX;root=Null;
}
void rot(node *&t,bool d){
node *p=t->c[d];
t->c[d]=p->c[!d];
p->c[!d]=t;
t->rz();p->rz();
t=p;
}
void _insert(node *&t,int x){
if(t==Null){
t=new node(x,Null);
return ;
}
bool d=x>t->val;
_insert(t->c[d],x);
if(t->c[d]->key<t->key)
rot(t,d);
else
t->rz();
}
void _del(node *&t,int x){
if(t->val==x){
bool d=t->c[0]->key<t->c[1]->key;
if(t->c[d]==Null){
delete t;
t=Null;
return;
}
rot(t,d);
_del(t->c[!d],x);
}else{
bool d=x>t->val;
_del(t->c[d],x);
}
t->rz();
}
int _rank(node *&t,int x){
if(t==Null)return 0;
int r=t->c[0]->size;
if(x==t->val)return r;
if(x<t->val)return _rank(t->c[0],x);
else return r+1+_rank(t->c[1],x);
}
void _deb(node *&t){
printf("val:%d size:%d\n",t->val,t->size);
if(t->c[0]!=Null){
printf("L: ");_deb(t->c[0]);
}
if(t->c[1]!=Null){
printf("R: ");_deb(t->c[1]);
}
}
void deb(){_deb(root);}
void insert(int x){_insert(root,x);}
void del(int x){_del(root,x);}
int rank(int x){return _rank(root,x);}
int size(){return root->size;}
};
Treap d[maxn];
int lowbit(int x){
return x&(-x);
}
void updata(int x,int val){
while(x<=n){
d[x].insert(val);
x+=lowbit(x);
}
}
int get(int x,int val){
if(x==0)return 0;
int ans=0;
while(x){
ans+=d[x].rank(val);
x-=lowbit(x);
}
return ans;
}
int size(int x){
if(x==0)return 0;
int ans=0;
while(x){
ans+=d[x].size();
x-=lowbit(x);
}
return ans;
}
long long anss[maxm];
int p[maxn];
long long ans=0;
int main(){
// freopen("1.txt","r",stdin);
// freopen("3.txt","w",stdout);
n=getint();m=getint();
for(int i=1;i<=n;i++)a[i]=getint(),p[a[i]]=i;
for(int i=1;i<=m;i++)b[i]=getint(),hash[b[i]]=1;
for(int i=1;i<=n;i++){
if(!hash[a[i]]){
updata(i,a[i]);
ans+=get(n,a[i])-get(i,a[i]);
ans+=size(i-1)-get(i-1,a[i]);
//T.Change(1,1,n,i,a[i]);
//ans+=T.Rank(1,1,n,i+1,n,a[i]);
//ans+=T.size(1,1,n,1,i-1)-T.Rank(1,1,n,1,i-1,a[i]);
//T.deb();
}
}
for(int i=m;i>=1;i--){
updata(p[b[i]],b[i]);
ans+=get(n,b[i])-get(p[b[i]],b[i]);
ans+=size(p[b[i]]-1)-get(p[b[i]]-1,b[i]);
//ans+=T.Rank(1,1,n,p[b[i]]+1,n,b[i]);
//ans+=T.size(1,1,n,1,p[b[i]]-1)-T.Rank(1,1,n,1,p[b[i]]-1,b[i]);
//T.deb();cout<<endl;
anss[i]=ans;
}
for(int i=1;i<=m;i++)
printf("%lld\n",anss[i]);
return 0;
}