题意
两列$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 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9462193.html
时间: 2024-10-04 05:09:16