zoukankan      html  css  js  c++  java
  • codeforces 425D

    题意:给定n<=100000个二维点,并且0<=x,y<=100000,求有多少个平行于坐标轴的正方形

    思路:本来想hash的,但是感觉不好弄。。

            后来感觉像是分块,最坏的情况就是那种x,y点稠密在一起的情况,并且x与y大致相同的情况下答案最多。。

            然后就想到了跟分块很像的暴力。

            对于每个点,用vx[x]记录有p.x==x的点的y,用vy[y]记录p.y==y的x

            那么对于每个vx[], vy[]排序。。

            接着对于每个点我们统计以它为右上角的正方形。。

            那么对于每个点(x, y),我们二分查找x处于vy[y]的位置ty,我们二分查找y处于vx[x]的位置tx

            那么如果tx<ty,我们直接统计vx[x][0]~vx[x][tx-1]的所有y是否有符合的

            每次判断可以通过使用二分查找其他点是否存在。。

            如果tx>=ty则统计vy[y][0]~vy[y][ty-1]的所有y是否符合。方法类似。

            这样最坏情况下应该跟分块的复杂度差不多吧(不会证明)

    code:

     1 #include <bits/stdc++.h>
     2 #define M0(x) memset(x, 0, sizeof(x))
     3 #define MP make_pair
     4 #define PB push_back
     5 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)
     6 using namespace std;
     7 #define x first
     8 #define y second
     9 const int maxn = 101010;
    10 pair<int, int> p[maxn];
    11 vector<int> vx[maxn], vy[maxn];
    12 int n, m;
    13 
    14 void solve(){
    15      int mx = 0, my = 0;
    16      repf(i, 1, n){
    17          scanf("%d%d", &p[i].x, &p[i].y);
    18          mx = max(p[i].x, mx);
    19          my = max(p[i].y, my);
    20      }
    21      repf(i, 0, mx) vx[i].clear();
    22      repf(i, 0, my) vy[i].clear();
    23      repf(i, 1, n){
    24           vx[p[i].x].PB(p[i].y);
    25           vy[p[i].y].PB(p[i].x);
    26      }
    27      repf(i, 0, mx) sort(vx[i].begin(), vx[i].end());
    28      repf(i, 0, my) sort(vy[i].begin(), vy[i].end());
    29      int ans = 0;
    30      int tx, ty, x, y, t2, t3, d, nx, ny;
    31      repf(i, 1, n){
    32          x = p[i].x, y = p[i].y;
    33          tx = lower_bound(vx[x].begin(), vx[x].end(), y) - vx[x].begin();
    34          ty = lower_bound(vy[y].begin(), vy[y].end(), x) - vy[y].begin();
    35          if (tx < ty){
    36                t2 = ty;
    37                for (int j = tx-1; j >= 0; --j){
    38                      d = y - vx[x][j];
    39                      nx = x - d;
    40                      t2 = lower_bound(vy[y].begin(), vy[y].end(), nx) - vy[y].begin();
    41                      if (vy[y][t2] == nx){
    42                           t3 = lower_bound(vx[nx].begin(), vx[nx].end(), vx[x][j]) - vx[nx].begin();
    43                           if (vx[nx][t3] == vx[x][j]) ++ans;
    44                      }
    45                }
    46                continue;
    47          }
    48 //         t2 = tx;
    49          for (int j = ty-1; j >= 0; --j){
    50                  d = x - vy[y][j];
    51                  ny = y - d;
    52                  t2 = lower_bound(vx[x].begin(), vx[x].end(), ny) - vx[x].begin();
    53                  if (vx[x][t2] == ny){
    54                       t3 = lower_bound(vy[ny].begin(), vy[ny].end(), vy[y][j]) - vy[ny].begin();
    55                       if (vy[ny][t3] == vy[y][j]) ++ans;
    56                  }
    57          }
    58      }
    59      cout << ans << endl; 
    60 }
    61 
    62 int main(){
    63 //    freopen("a.in", "r", stdin);
    64 //    freopen("a.out", "w", stdout);
    65     while (scanf("%d", &n) != EOF){
    66         solve();
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    第九章 引用
    第八章 指针
    第六章 面向对象
    第五章 if语句与运算符
    第四章 C++数据类型
    第三章 初步了解函数
    第二章 做一个简短的C++程序
    第一章 初始C++
    vs2012 快捷键+方法
    vue如何修改生效日期范围,以及转化成yyyy-mm-dd的格式
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4066266.html
Copyright © 2011-2022 走看看