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;
    }
    

      

  • 相关阅读:
    [导入]匹配正则表达式的函数BOOL型(修正一下)
    [导入]得到当前网页文件名(不含路径)的小函数,如果有效率更高的请回帖评论
    [导入]约瑟夫环VC2005
    [导入]《菊花台》的歌词LRC文件
    [导入]一段不太好的代码:IE主页不是本站地址就不充许访问或下载
    [导入]ALASTART.EXE木马清除
    [导入]编程意识
    [导入]人若其名
    vueresource安装与使用
    com复合文档存储及持久化
  • 原文地址:https://www.cnblogs.com/clrs97/p/4858111.html
Copyright © 2011-2022 走看看