zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    课堂练习
    日程管理测试用例
    日程管理APP的测试计划和测试矩阵
    日程管理Bug Report
    图书管理系统活动图
    团队如何做决定?
    课堂练习
    课堂练习(NABCD Model)
    课堂练习
    日程管理的测试计划和测试矩阵
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9462193.html
Copyright © 2011-2022 走看看