bzoj3295: [Cqoi2011]動態逆序對
阿新 • • 發佈:2018-03-06
lowbit 包含 point gpo for oid sort register open
3295: [Cqoi2011]動態逆序對
Description
? 對於序列A,它的逆序對數定義為滿足i
Input
輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。
以下n行每行包含一個1到n之間的正整數,即初始排列。
以下m行每行一個正整數,依次為每次刪除的元素。
Output
輸出包含m行,依次為刪除每個元素之前,逆序對的個數。
數據範圍
$N \leqslant 100000 , M \leqslant50000 $
這道題將插入時間轉化為一維,就是個三維偏序,直接cdq即可。
註意輸入的是元素大小,而不是元素個數。
#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
inline int read(){
int x;
char c;
int f=1;
while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
if (c==‘-‘) c=getchar(),f=-1;
x=c^‘0‘;
while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1)+(x<<3)+(c^‘0‘);
return x*f;
}
inline ll readll(){
ll x;
char c;
ll f=1;
while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
if(c==‘-‘) c=getchar(),f=-1;
x=c^‘0‘ ;
while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1ll)+(x<<3ll)+(c^‘0‘);
return x*f;
}
inline bool chkmax(int &x,int y){return (y>x)?(x=y,1):0;}
inline bool chkmin(int &x,int y){return (y<x)?(x=y,1):0;}
const int maxn=1e5+10;
struct point{
int x,y,z,sum;
}a[maxn];
bool cmpx(const point A,const point B){
if(A.x!=B.x) return A.x<B.x;
if(A.y!=B.y) return A.y<B.y;
return A.z<B.z;
}
bool cmpy(const point A,const point B){
if(A.y!=B.y) return A.y<B.y;
return A.z<B.z;
}
int n;
ll ans[maxn];
struct szsz{
int c[maxn];
int lowbit(int x){
return x&(-x);
}
int sum(int x){
int res=0;
while(x){
res+=c[x];
x-=lowbit(x);
}
return res;
}
void add(int x,int y){
while(x<=n){
c[x]+=y;
x+=lowbit(x);
}
}
}bit;
void cdq(int L,int R){
if(L>=R) return;
int Mid=(L+R)>>1;
cdq(L,Mid),cdq(Mid+1,R);
sort(a+L,a+Mid+1,cmpy),sort(a+Mid+1,a+R+1,cmpy);
int j=L;
for(int i=Mid+1;i<=R;++i){
while(j<=Mid && a[j].y<=a[i].y) bit.add(a[j].z,1),++j;
a[i].sum+=bit.sum(n)-bit.sum(a[i].z);
}
REP(i,L,j-1) bit.add(a[i].z,-1);
j=Mid;
for(int i=R;i>Mid;--i){
while(j>=L && a[j].y>=a[i].y) bit.add(a[j].z,1),--j;
a[i].sum+=bit.sum(a[i].z);
}
DREP(i,Mid,j+1) bit.add(a[i].z,-1);
}
int mp[maxn];
int main(){
#ifndef ONLINE_JUDGE
freopen("cdq.in","r",stdin);
freopen("cdq.out","w",stdout);
#endif
n=read();int m=read();
REP(i,1,n) a[i].x=0,a[i].y=i,a[i].z=read(),mp[a[i].z]=i;
int num=n;
REP(i,1,m){
int x=read();x=mp[x];
a[x].x=num--;
}
REP(i,1,m) if(a[i].x==0) a[i].x=num--;
sort(a+1,a+n+1,cmpx);
cdq(1,n);
REP(i,1,n) ans[a[i].x]+=a[i].sum;
REP(i,1,n) ans[i]+=ans[i-1];
DREP(i,n,n-m+1) printf("%lld\n",ans[i]);
return 0;
}
bzoj3295: [Cqoi2011]動態逆序對