http://www.elijahqi.win/archives/3206
Description
Farmer John is continuing to ponder the issue of cows crossing the road through his farm, introduced
in the preceding two problems. He realizes now that the threshold for friendliness is a bit more su
btle than he previously considered – breeds aa and bb are now friendly if |a-b|≤K, and unfriendly
otherwise.Given the orderings of fields on either side of the road through FJ’s farm, please count t
he number of unfriendly crossing pairs of breeds, where a crossing pair of breeds is defined as in t
he preceding problems.
思考过前两个问题后,农民约翰正在继续思考如何对付穿过农场的牛的问题。 他现在意识到,友好的品种的标准
比他以前想的稍微微妙一些 -对于品种a,b,如果|a - b|≤K,现在是友好的。 否则是不友好的。给定这条路两边
的田地的顺序,请计算有多少交叉的不良品种对,其中一对品种在前问题被定义。
Input
The first line of input contains N (1≤N≤100,000) and K (0≤K
#include<cstdio>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int N=100100;
struct node{
int a,b,tim;
}qr[N],tmp[N];
int s[N],n,k;ll ans;
inline void add(int x,int v){while(x<=n) s[x]+=v,x+=x&-x; }
inline int query(int x){static int tmp;
if (x<0) return 0;
for (tmp=0;x;x-=x&-x) tmp+=s[x];return tmp;
}
inline void clear(int x){
while(x<=n) if (!s[x]) return;else s[x]=0,x+=x&-x;
}
inline bool cmp(const node &a,const node &b){return a.a>b.a;}
inline void cdq(int l,int r){
if (l==r) return;int mid=l+r>>1;
cdq(l,mid);cdq(mid+1,r);int l1=l,l2=mid+1,now=l,cnt=0;
while(l1<=mid&&l2<=r){
if (qr[l1].b<qr[l2].b) ++cnt,tmp[now]=qr[l1],add(qr[l1].tim,1),++now,++l1;else tmp[now]=qr[l2],
ans+=query(qr[l2].tim-k-1),ans+=qr[l2].tim+k+1>n?0:(cnt-query(qr[l2].tim+k)),++now,++l2;
}while(l1<=mid) tmp[now]=qr[l1],++now,++l1;
while(l2<=r) tmp[now]=qr[l2],ans+=query(qr[l2].tim-k-1),
ans+=qr[l2].tim+k>n?0:(cnt-query(qr[l2].tim+k)),++now,++l2;
for (int i=l;i<=r;++i) qr[i]=tmp[i],clear(qr[i].tim);
}
int main(){
freopen("bzoj4991.in","r",stdin);
n=read();k=read();
for (int i=1;i<=n;++i) qr[read()].a=i,qr[i].tim=i;
for (int i=1;i<=n;++i) qr[read()].b=i;sort(qr+1,qr+n+1,cmp);
cdq(1,n);printf("%lld\n",ans);
// for (int i=1;i<=cnt;++i) printf("%d %d %d %d\n",qr[i].tim,qr[i].a,qr[i].b,qr[i].op);
return 0;
}