[USACO17FEB]Why Did the Cow Cross the Road III P(CDQ分治)

题意

两列$n$的排列,相同的数连边,如果一对数有交叉且差的绝对值$>k$,则$++ans$,求$ans$

题解

可以把每一个数字看成一个三元组$(x,y,z)$,其中$x$表示在第一列的位置,$y$表示在第二列的位置,$z$表示权值

两条线交叉,就是$x<x'$且$y>y'$,又要满足差值的绝对值小于等于$k$,就是$|z-z'|<=k$

于是就转化为了一个三维偏序问题,直接上CDQ

具体细节请看代码

 1 // luogu-judger-enable-o2
 2 //minamoto
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<algorithm>
 6 #define ll long long
 7 using namespace std;
 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 9 char buf[1<<21],*p1=buf,*p2=buf;
10 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
11 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
12 inline int read(){
13     #define num ch-'0'
14     char ch;bool flag=0;int res;
15     while(!isdigit(ch=getc()))
16     (ch=='-')&&(flag=true);
17     for(res=num;isdigit(ch=getc());res=res*10+num);
18     (flag)&&(res=-res);
19     #undef num
20     return res;
21 }
22 const int N=1e5+5;
23 int n,k,b[N];
24 ll ans;int c[N];
25 inline void add(int x){
26     for(;x<=n;x+=x&-x) c[x]+=1;
27 }
28 inline void clear(int x){
29     for(;x<=n;x+=x&-x)
30     if(c[x]) c[x]=0;
31     else break;
32 }
33 inline int query(int x){
34     int res=0;x=x>n?n:x;if(x<=0) return 0;
35     for(;x;x-=x&-x) res+=c[x];
36     return res;
37 }
38 struct node{
39     int x,y,z;
40     node(){}
41     node(int x,int y,int z):x(x),y(y),z(z){}
42     inline bool operator <(const node &b)const
43     {return x!=b.x?x<b.x:
44             y!=b.y?y>b.y:
45             z<b.z;}
46 }a[N],p[N];
47 void CDQ(int l,int r){
48     if(l==r) return;
49     int mid=l+r>>1;
50     CDQ(l,mid),CDQ(mid+1,r);
51     for(int j=mid+1,i=l;j<=r;++j){
52         while(i<=mid&&a[i].y>a[j].y) add(a[i++].z);
53         ans+=1ll*query(a[j].z-k-1)+query(n)-query(a[j].z+k);
54     }
55     for(int i=l;i<=mid;++i) clear(a[i].z);
56     for(int i=l,j=l,k=mid+1;i<=r;){
57         if(k>r||(j<=mid&&a[j].y>a[k].y)) p[i++]=a[j++];
58         else p[i++]=a[k++];
59     }
60     for(int i=l;i<=r;++i) a[i]=p[i];
61 }
62 int main(){
63     //freopen("testdata.in","r",stdin);
64     n=read(),k=read();
65     for(int i=1;i<=n;++i){
66         int x=read();b[x]=i;
67     }
68     for(int i=1;i<=n;++i){
69         int x=read();
70         a[i]=node(b[x],i,x);
71     }
72     sort(a+1,a+1+n);
73     CDQ(1,n);
74     printf("%lld",ans);
75     return 0;
76 }

 

posted @ 2018-08-12 10:37  bztMinamoto  阅读(205)  评论(0编辑  收藏  举报
Live2D