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
  • 相关阅读:
    封装成帧、帧定界、帧同步、透明传输(字符计数法、字符串的首尾填充法、零比特填充的首尾标志法、违规编码法)
    计算机网络之数据链路层的基本概念和功能概述
    物理层设备(中继器、集线器)
    计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)
    计算机网络之编码与调制
    0953. Verifying an Alien Dictionary (E)
    1704. Determine if String Halves Are Alike (E)
    1551. Minimum Operations to Make Array Equal (M)
    0775. Global and Local Inversions (M)
    0622. Design Circular Queue (M)
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4066266.html
Copyright © 2011-2022 走看看