zoukankan      html  css  js  c++  java
  • BZOJ1807 : [Ioi2007]Pairs 彼此能听得见的动物对数

    一维的情况:

    排序后维护一个单调指针即可,时间复杂度$O(nlog n)$。

    二维的情况:

    旋转坐标系后转化为二维数点问题,扫描线+树状数组维护即可,时间复杂度$O(nlog n)$。

    三维的情况:

    将后两维旋转坐标系,对于每个x,预处理出横坐标为x的点的后两维的二维前缀和。

    枚举一个点,再枚举另一个点的x,在相应坐标的二维前缀和里查询正方形内点的个数即可,时间复杂度$O(nm)$。

    #include<cstdio>
    #include<algorithm>
    #define N 300010
    using namespace std;
    int n,m,i,D;long long ans;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    namespace task1{
    int a[N],i,j;
    void solve(){
      for(i=1;i<=n;i++)read(a[i]);
      sort(a+1,a+n+1);
      for(i=j=1;i<=n;ans+=i-j,i++)while(a[i]-a[j]>D)j++;
    }
    }
    namespace task2{
    int m,k,i,x,y,z,bit[N],q[N],X,Y,b[N];
    struct P{int x,y,z,t;P(){}P(int _x,int _y,int _z,int _t){x=_x,y=_y,z=_z,t=_t;}}a[N];
    inline bool cmp(const P&a,const P&b){return a.x==b.x?a.t<b.t:a.x<b.x;}
    inline int lower(int x){
      int l=1,r=m,t,mid;
      while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline void add(int x,int y){for(;x<=m;x+=x&-x)bit[x]+=y;}
    inline int ask(int x){int t=0;for(;x;x-=x&-x)t+=bit[x];return t;}
    void solve(){
      for(m=0,z=D,i=1;i<=n;i++){
        read(x),read(y),X=x+y,Y=x-y;
        a[++m]=P(X,Y,0,i),b[m]=Y;
        a[++m]=P(X+z,Y-z,Y+z,n+1),b[m]=Y-z;
        a[++m]=P(X-z,Y-z,Y+z,0),b[m]=Y+z;
      }
      for(sort(a+1,a+m+1,cmp),sort(b+1,b+m+1),i=1;i<=m;i++){
        if(a[i].t&&a[i].t<=n)ans+=ask(lower(a[i].y));
        else{
          a[i].y=lower(a[i].y),a[i].z=lower(a[i].z)+1;
          if(a[i].t)add(a[i].y,-1),add(a[i].z,1);else add(a[i].y,1),add(a[i].z,-1);
        }
      }
      ans=(ans-n)/2;
    }
    }
    namespace task3{
    int i,j,k,x,y,z,X,Y,a[N][3],s[76][152][152];
    inline int ask(int x,int y){return s[j][max(min(x,150),0)][max(min(y,150),0)];}
    void solve(){
      for(i=1;i<=n;i++){
        read(x),read(y),read(z),X=y+z,Y=y-z+75;
        a[i][0]=x,a[i][1]=X,a[i][2]=Y;
        s[x][X][Y]++;
      }
      for(i=1;i<=75;i++)for(j=1;j<=150;j++)for(k=1;k<=150;k++)s[i][j][k]+=s[i][j-1][k]+s[i][j][k-1]-s[i][j-1][k-1];
      for(i=1;i<=n;i++)for(j=1;j<=75;j++)if(abs(a[i][0]-j)<=D){
        x=D-abs(a[i][0]-j);
        ans+=ask(a[i][1]+x,a[i][2]+x)-ask(a[i][1]-x-1,a[i][2]+x)-ask(a[i][1]+x,a[i][2]-x-1)+ask(a[i][1]-x-1,a[i][2]-x-1);
      }
      ans=(ans-n)/2;
    }
    }
    int main(){
      read(m),read(n),read(D),read(i);
      if(m==1)task1::solve();
      if(m==2)task2::solve();
      if(m==3)task3::solve();
      return printf("%lld",ans),0;
    }
    

      

  • 相关阅读:
    165. Compare Version Numbers
    164. Maximum Gap
    3、桶排序
    162. Find Peak Element
    160. Intersection of Two Linked Lists
    155. Min Stack
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    Linux/Unix系统编程手册 第二章:基本概念
    Linux/Unix系统编程手册 第一章:历史和标准
  • 原文地址:https://www.cnblogs.com/clrs97/p/4858111.html
Copyright © 2011-2022 走看看