P3157 [CQOI2011]动态逆序对
原题地址
此处写的是cdq分治板子题(三维偏序)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define For(i,x,y) for(ll i=(x);i<=(y);++i)
#define FOr(i,x,y) for(ll i=(x);i>=(y);--i)
#define rep(i,x,y) for(ll i=(x);i<(y);++i)
#define clr(a,v) memset(a,v,sizeof(a))
#define cpy(a,b) memcpy(a,b,sizeof(a))
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define pa pair<ll,ll>
#define y1 y11111111111111
#define debug puts("@@@@@@@@@@@@@@@@@@@@@@@")
ll read(){
ll x=0,f=1; char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void write(ll x){
if (x<0) putchar('-'),write(-x);
else{
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
#define lowbit(x) (x&(-x))
const int N = 200005;
ll n,m;
ll b[N];
struct node{
ll val,ans,del;
}a[N];
ll res[N];
inline void change(ll x,ll v){ for(;x<=n+1;x += lowbit(x)) b[x] += v; }
inline ll query(ll x){ll ans = 0; for(;x;x -= lowbit(x)) ans += b[x]; return ans;}
inline bool cmp(node a,node b){
return a.del < b.del;
}
inline bool cmp2(node a,node b){
return a.val < b.val;
}
inline void cdq(ll l,ll r){
if(l == r) return;
ll mid = (l+r)>>1;
cdq(l,mid); cdq(mid+1,r);
ll i = l,j = mid+1;
while(i <= mid){
while(a[i].val > a[j].val && j <= r) change(a[j].del,1),++j;
a[i].ans += query(m) - query(a[i].del-1);
++i;
}
i = l,j = mid+1;
while(i <= mid){
while(a[i].val > a[j].val && j <= r) change(a[j].del,-1),++j;
++i;
}
i = mid; j = r;
while(j >= mid+1){
while(a[j].val < a[i].val && i >= l) change(a[i].del,1),--i;
a[j].ans += query(m) - query(a[j].del-1);
--j;
}
i = mid; j = r;
while(j >= mid+1){
while(a[j].val < a[i].val && i >= l) change(a[i].del,-1),--i;
--j;
}
sort(a+l,a+r+1,cmp2); //偷懒使用sort
}
signed main(){
n = read(),m = read();
For(i,1,n){
a[i].val = read();
res[a[i].val] = i;
}
For(i,1,m){
ll x = read();
a[res[x]].del = i;
}
For(i,1,n) if(a[i].del == 0) a[i].del = m+1;
ll ans = 0;
For(i,1,n){
ans += query(n)-query(a[i].val-1);
change(a[i].val,1);
}
For(i,1,n) change(a[i].val,-1);
m = m+1;
cdq(1,n);
sort(a+1,a+n+1,cmp);
rep(i,1,m){
printf("%lld\n",ans);
ans -= a[i].ans;
}
}