Problem:
G - 村
問題文
きつねのしえるは，休暇でとある小さな村を訪れている．彼女が驚いたのは，その村の表札がもつ性質である．
村には
N
個の家屋がある．ここでは簡単のため，村は 2 次元平面であるとし，家屋はこの平面上の点であると見なす．
それぞれの家屋には表札が 1 個設けられており，その家の苗字を表していた．しえるは村の中を訪問するにつれて，この村の表札が次のような性質を持っていることに気付いた．
ある実数
R
が存在する．
もし 2 つの家屋の距離が
R
以下であるなら，その 2 つの家屋は同じ表札を持つ．
もし 2 つの家屋の距離が
3R
以上であるなら，その 2 つの家屋は異なる表札を持つ．
任意の 2 つの家屋の距離は
R
以下であるか
3R
以上であるかのどちらかである．
ここで，家屋同士の距離は，平面上のユークリッド距離によって計測するものとする．
しえるはこの村に表札が全部で何種類あるのかが気になったが，この村は意外に広いということに気付いたので，計算機を使ってこの答えを模索することにした．
入力形式
入力は以下の形式で与えられる．
N
R
x
1
y
1
x
2
y
2
...
x
N
y
N
N
は家屋の個数である．
R
は家屋の配置の制約に関する値である．
(x
i
, y
i
)
は家屋
i
の座標を表す．
出力形式
村に存在する表札の種類の数を求めよ．
制約
1 ≤ N ≤ 2 × 10
5
1 ≤ R ≤ 10
3
|x
i
|, |y
i
| ≤ 10
6
N
は整数である．
R, x
i
, y
i
は実数で，小数第 3 位まで表される．
任意の
1 ≤ i < j ≤ N
に対して
d
ij
= √{(x
i
- x
j
)
2
+ (y
i
- y
j
)
2
}
とおくとき，
d
ij
≤ R
か
3R ≤ d
ij
のどちらかが満たされる．
この問題の判定には，15 点分のテストケースのグループが設定されている． このグループに含まれるテストケースは上記の制約に加えて下記の制約も満たす．
答えは 10 以下である．
入出力例
入力例 1
5 3.000
1.000 0.000
0.000 0.000
-1.000 0.000
10.000 0.000
-10.000 0.000
出力例 1
3
家屋 1,2,3 と家屋 4 と家屋 5 で表札が異なる．全体で 3 つの表札が存在する．
入力例 2
12 1.234
0.500 0.000
-0.500 0.000
0.000 0.000
0.000 -0.500
55.500 55.000
-55.500 55.000
55.000 55.000
55.000 -55.500
99.500 99.000
-99.500 99.000
99.000 99.000
99.000 -99.500
出力例 2
7
入力例 3
5 99.999
0.000 0.000
49.999 0.001
0.000 0.000
-49.999 -0.001
0.000 0.000
出力例 3
1
Writer: 楠本充
Tester: 小浜翔太郎

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <utility>
#include <cstdint>
using namespace std;

struct DSU {
    vector<int> p, sz;
    DSU(int n) : p(n), sz(n, 1) { for (int i = 0; i < n; ++i) p[i] = i; }
    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }
    void unite(int a, int b) {
        a = find(a); b = find(b);
        if (a == b) return;
        if (sz[a] < sz[b]) swap(a, b);
        p[b] = a; sz[a] += sz[b];
    }
};

struct PairHash {
    size_t operator()(const pair<long long,long long>& v) const {
        return hash<long long>()((v.first<<32) ^ v.second);
    }
};

long long parseScaled(const string& s) {
    int sign = 1;
    size_t i = 0;
    if (s[i] == '-') { sign = -1; i++; }
    long long ip = 0, fp = 0;
    while (i < s.size() && s[i] != '.') { ip = ip*10 + (s[i]-'0'); i++; }
    if (i < s.size() && s[i] == '.') {
        i++;
        int k = 0;
        while (i < s.size() && k < 3 && s[i] != ' ') { fp = fp*10 + (s[i]-'0'); i++; k++; }
        while (k < 3) { fp *= 10; k++; }
    } else {
        fp = 0;
    }
    return sign * (ip*1000 + fp);
}

long long floor_div(long long a, long long b) {
    if (a >= 0) return a / b;
    return - ((-a + b - 1) / b);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    string Rs;
    if (!(cin >> N >> Rs)) return 0;
    long long R = parseScaled(Rs);
    long long R2 = R * R;

    vector<long long> x(N), y(N);
    for (int i = 0; i < N; ++i) {
        string xs, ys;
        cin >> xs >> ys;
        x[i] = parseScaled(xs);
        y[i] = parseScaled(ys);
    }

    DSU dsu(N);
    unordered_map<pair<long long,long long>, vector<int>, PairHash> cells;
    cells.reserve(N*2);

    for (int i = 0; i < N; ++i) {
        long long cx = floor_div(x[i], R);
        long long cy = floor_div(y[i], R);
        bool linked = false;
        for (int dx = -1; dx <= 1 && !linked; ++dx) {
            for (int dy = -1; dy <= 1 && !linked; ++dy) {
                auto it = cells.find({cx + dx, cy + dy});
                if (it == cells.end()) continue;
                const vector<int>& vec = it->second;
                for (int j : vec) {
                    long long dxv = x[i] - x[j];
                    long long dyv = y[i] - y[j];
                    if (dxv*dxv + dyv*dyv <= R2) {
                        dsu.unite(i, j);
                        linked = true;
                        break;
                    }
                }
            }
        }
        cells[{cx, cy}].push_back(i);
    }

    int cnt = 0;
    for (int i = 0; i < N; ++i) if (dsu.find(i) == i) cnt++;
    cout << cnt << '\n';
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 28020
final_rank: 8

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 998244353 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};
struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};

int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);
  
  int n; double r;
  cin >> n >> r;
  set<pair<int, int>> st;int ans = 0;
  REP(i,n) {
    double x, y; cin >> x >> y;
    x = floor(x/r), y = floor(y/r);
    bool f = false;
    for(int j=-1; j<=1; j++) {
      for(int k=-1; k<=1; k++) {
        if(st.find({x+j,y+k}) != st.end()) f = true;
      }
    }
    if(!f) ans++;
    st.insert({x, y});
  }
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 12040
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <utility>
using namespace std;
int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0 ,1};

void dfs(pair<int, int> curr, set<pair<int, int> > &block){
    if(block.find(curr) == block.end()) return;
    block.erase(curr);
    for(int i=0; i<8; i++){
        dfs(make_pair(curr.first +dx[i], curr.second +dy[i]), block);
    }
}

int main(){
    int n;
    double r;
    cin >> n >> r;

    set<pair<int, int> > block; 
    for(int i=0; i<n; i++){
        double x,y;
        cin >> x >> y;
        int xi = (x +1e6)/r;
        int yi = (y +1e6)/r;
        block.insert(make_pair(xi, yi));
    }

    int ans = 0;
    while(!block.empty()){
        ans++;
        pair<int, int> curr = *(block.begin());
        dfs(curr, block);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 11716
final_rank: 3

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

int n;
double r;
vector<pair<int,int> > vec; 
set<pair<int,int> > visited;
set<pair<int,int> > exist;

int main(){
  
  scanf("%d%lf", &n,&r);

  for(int i=0;i<n;i++){
    double x,y;
    scanf("%lf%lf", &x, &y);
    if(x >= 0) x += r;
    if(y >= 0) y += r;
    vec.push_back({x/r, y/r});
    exist.insert(vec[i]);
  }

  int ans = 0;

  int dx[8] = {0,0,1,-1,1,1,-1,-1};
  int dy[8] = {1,-1,0,0,1,-1,1,-1};
  
  for(int i=0;i<n;i++){
    if(visited.find(vec[i]) != visited.end())
      continue;

    ans++;

    queue<pair<int,int> > que;
    que.push(vec[i]);
    while(que.size()){
      auto p = que.front();
      que.pop();
      
      if(visited.find(p) != visited.end()) continue;
      visited.insert(p);
      
      for(int j=0;j<8;j++){
        if(exist.find({p.first + dx[j], p.second + dy[j]}) != exist.end())
          que.push({p.first + dx[j], p.second + dy[j]});
      }
    }
  }

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 21416
final_rank: 7

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"


int main() {
	int N;cin>>N;
	ld R;cin>>R;
	vector<pair<ld,ld>>houses;
	for (int i = 0; i < N; ++i) {
		ld a,b;cin>>a>>b;
		houses.push_back(make_pair(a,b));
	}

	int ans=0;
	vector<int>used(N,false);
	for (int i = 0; i < N; ++i) {
		if (!used[i]) {
			ans++;
			used[i]=true;
			for (int j = 0; j < N; ++j) {
				if (!used[j]) {
					ld dx=houses[i].first-houses[j].first;
					ld dy=houses[i].second-houses[j].second;
					ld len=dx*dx+dy*dy;
					if (len <= R*R) {
						used[j]=true;
					}
				}
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 0.4090909090909091
time_ms: 200
memory_kb: 11348
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pl = pair<ll,ll>;

struct UF{
    int n;
    //正だったらその頂点の親,負だったら根で連結成分の個数
    vector<int> d;
    UF() {}
    UF(int N):n(N), d(N,-1){}
    int root(int v){
        if(d[v]<0) return v;
        return d[v]=root(d[v]);
    }
    bool unite(int X,int Y){
        X=root(X); Y=root(Y);
        if(X==Y) return false;
        if(size(X) < size(Y)) swap(X,Y);
        d[X]+=d[Y];
        d[Y]=X;
        return true;
    }
    int size(int v){ return -d[root(v)]; }
    bool same(int X,int Y){ return root(X)==root(Y); }
};

ll read()
{
    string s;
    cin >>s;

    int m = 1;
    if(s[0]=='-')
    {
        m = -1;
        s = s.substr(1);
    }

    int S = s.size();
    ll ret = atoll(s.substr(0,S-4).c_str())*1000 + atoll(s.substr(S-3).c_str());

    return m*ret;
}

int main()
{
    int n;
    scanf(" %d", &n);

    ll R = read();

    vector<pl> p(n);
    rep(i,n)
    {
        ll x=read(), y=read();
        p[i] = {x,y};
    }
    sort(all(p));

    UF uf(n);
    int idx = 0;
    set<pl> now;
    rep(i,n)
    {
        while(idx<n && p[idx].fi<=p[i].fi+R)
        {
            now.insert({p[idx].se,idx});
            ++idx;
        }

        auto itr = now.lower_bound({p[i].se-R,-1});
        while(itr!=now.end() && itr->fi<=p[i].se+R)
        {
            int id = itr->se;
            uf.unite(i,id);
            itr = now.erase(itr);
        }
    }

    set<int> s;
    rep(i,n) s.insert(uf.root(i));
    cout << s.size() << endl;
    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 19328
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pl = pair<ll,ll>;

struct UF{
    int n;
    //正だったらその頂点の親,負だったら根で連結成分の個数
    vector<int> d;
    UF() {}
    UF(int N):n(N), d(N,-1){}
    int root(int v){
        if(d[v]<0) return v;
        return d[v]=root(d[v]);
    }
    bool unite(int X,int Y){
        X=root(X); Y=root(Y);
        if(X==Y) return false;
        if(size(X) < size(Y)) swap(X,Y);
        d[X]+=d[Y];
        d[Y]=X;
        return true;
    }
    int size(int v){ return -d[root(v)]; }
    bool same(int X,int Y){ return root(X)==root(Y); }
};

ll read()
{
    double t;
    scanf(" %lf", &t);
    return t*1000;
}

int main()
{
    int n;
    scanf(" %d", &n);

    ll R = read();

    vector<pl> p(n);
    rep(i,n)
    {
        ll x=read(), y=read();
        p[i] = {x,y};
    }
    sort(all(p));

    UF uf(n);
    int idx = 0;
    set<pl> now;
    rep(i,n)
    {
        while(idx<n && p[idx].fi<=p[i].fi+R)
        {
            now.insert({p[idx].se,idx});
            ++idx;
        }

        auto itr = now.lower_bound({p[i].se-R,-1});
        while(itr!=now.end() && itr->fi<=p[i].se+R)
        {
            int id = itr->se;
            uf.unite(i,id);
            itr = now.erase(itr);
        }
    }

    set<int> s;
    rep(i,n) s.insert(uf.root(i));
    cout << s.size() << endl;
    return 0;
}
accuracy: 0.5303030303030303
time_ms: 120
memory_kb: 9496
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pl = pair<ll,ll>;

struct UF{
    int n;
    //正だったらその頂点の親,負だったら根で連結成分の個数
    vector<int> d;
    UF() {}
    UF(int N):n(N), d(N,-1){}
    int root(int v){
        if(d[v]<0) return v;
        return d[v]=root(d[v]);
    }
    bool unite(int X,int Y){
        X=root(X); Y=root(Y);
        if(X==Y) return false;
        if(size(X) < size(Y)) swap(X,Y);
        d[X]+=d[Y];
        d[Y]=X;
        return true;
    }
    int size(int v){ return -d[root(v)]; }
    bool same(int X,int Y){ return root(X)==root(Y); }
};

ll read()
{
    double t;
    scanf(" %lf", &t);
    return t*1000;
}

int main()
{
    int n;
    scanf(" %d", &n);

    ll R = read();

    vector<pl> p(n);
    rep(i,n)
    {
        ll x=read(), y=read();
        p[i] = {x,y};
    }
    sort(all(p));

    UF uf(n);
    int idx = 0;
    set<pl> now;
    vector<bool> vis(n);
    rep(i,n)if(!vis[i])
    {
        vis[i] = true;
        while(idx<n && p[idx].fi<=p[i].fi+R)
        {
            now.insert({p[idx].se,idx});
            ++idx;
        }

        auto itr = now.lower_bound({p[i].se-R,-1});
        while(itr!=now.end() && itr->fi<=p[i].se+R)
        {
            int id = itr->se;
            uf.unite(i,id);
            vis[id]=true;
            itr = now.erase(itr);
        }
    }

    set<int> s;
    rep(i,n) s.insert(uf.root(i));
    cout << s.size() << endl;
    return 0;
}
accuracy: 0.5303030303030303
time_ms: 120
memory_kb: 9448
final_rank: 13

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

typedef pair<int,int> Point;

int diff_x[8] = {-1,0,1,-1,1,-1,0,1},diff_y[8] = {-1,-1,-1,0,0,1,1,1};
set<Point> SET;

int main(){

	int N;
	double R;

	scanf("%d %lf",&N,&R);

	double tmp_x,tmp_y;
	for(int i = 0; i < N; i++){
		scanf("%lf %lf",&tmp_x,&tmp_y);
		SET.insert(Point((int)(tmp_x/R),(int)(tmp_y/R)));
	}

	int ans = 0;

	while(SET.size() != 0){
		set<Point>::iterator it = SET.begin();
		Point point = *it;
		SET.erase(it);
		ans++;
		for(int i = 0; i < 8; i++){
			Point tmp = Point(point.first + diff_x[i],point.second + diff_y[i]);
			it = SET.find(tmp);
			if(it != SET.end())SET.erase(it);
		}
	}

	printf("%d\n",ans);
}
accuracy: 1
time_ms: 150
memory_kb: 11712
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<double,double> P;
typedef pair<int,int> PP;
 
double D(P a,P b) {return sqrt((a.F-b.F)*(a.F-b.F)+(a.S-b.S)*(a.S-b.S));}
const int N=222222;
int p[N],r[N];
void init(){for(int i=0; i<N; i++) p[i]=i,r[i]=0;}
int find(int x){return (p[x]==x)?x:(p[x]=find(p[x]));}
void unite(int x,int y) {
  x=find(x),y=find(y);
  if(x==y)return;
  if(r[x]<r[y])p[x]=y;
  else{p[y]=x;if(r[x]==r[y])r[x]++;}
}
 
int main() {
  init();
  int n;
  double d;
  cin>>n>>d;
  P a[n];
  for(int i=0; i<n; i++) cin>>a[i].F>>a[i].S;
  map<PP,int> m;
  for(int i=0; i<n; i++) {
    int x=floor(a[i].F/d),y=floor(a[i].S/d);
    for(int dx=-1; dx<2; dx++)for(int dy=-1; dy<2; dy++)if(m.count(PP(x+dx,y+dy))) unite(i,m[PP(x+dx,y+dy)]);
    m[PP(x,y)]=i;
  }
  set<int> s;
  for(int i=0; i<n; i++) s.insert(find(i));
  cout<<s.size()<<endl;
  return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 26912
final_rank: 10

code_snippet: #include<bits/stdc++.h>
#define EPS (1e-8)
#define N_MAX 200005
using namespace std;
typedef double ll;

int N;
ll R,x[N_MAX],y[N_MAX];
bool used[N_MAX];

struct node{
  vector<ll> Point;
  int l,r;
  node(){}
  node(vector<ll> a){Point=a,l=r=-1;}
};

const int K=2;// K:?¬??????°
int D;// D:?????????????????????????????????????¬????
vector<vector<ll> > P;// ???????????????????´????K+1???(K???????¬????????????????????????????number)
vector<node> G;

bool compare(const vector<ll> &A,const vector<ll> &B){return A[D]<B[D];}

int make_tree(int depth,int l,int r){
  if(l>r)return -1;
  D=depth%K;
  sort(P.begin()+l,P.begin()+r+1,compare);
  int m=(l+r)/2,res=G.size();
  G.push_back(node(P[m]));

  int vl=make_tree(depth+1,l,m-1);
  int vr=make_tree(depth+1,m+1,r);

  G[res].l=vl; G[res].r=vr;
  return res;
}

vector<int> num;// search??§?????????????????¨?????§????????????number????????????

void search(int x,int depth,vector<ll> &L,vector<ll> &R){
  bool f=true;
  for(int i=0;i<K;i++)
    if(G[x].Point[i]<L[i]||R[i]<G[x].Point[i])f=false;

  if(f)num.push_back(G[x].Point[K]);

  D=depth%K;
  if(G[x].Point[D]<=R[D]&&G[x].r!=-1)search(G[x].r,depth+1,L,R);
  D=depth%K;
  if(L[D]<=G[x].Point[D]&&G[x].l!=-1)search(G[x].l,depth+1,L,R);
}

int main(){
  
  cin>>N>>R;
  
  P.resize(N);
  
  for(int i=0;i<N;i++){
    
    scanf("%lf %lf",&x[i],&y[i]);
    
    P[i].resize(K+1);
    
    P[i][K]=i;
    P[i][0]=x[i],P[i][1]=y[i];
  }
  
  make_tree(0,0,P.size()-1);
 
  int ans=0;
  for(int i=0;i<N;i++){
    
    if(used[i])continue;
    
    vector<ll> L2(K),R2(K);
    
    L2[0]=x[i]-R-EPS;
    R2[0]=x[i]+R+EPS;
    
    L2[1]=y[i]-R-EPS;
    R2[1]=y[i]+R+EPS;
    
    num.clear();
    
    search(0,0,L2,R2);
    
    for(int j=0;j<num.size();j++) used[num[j]]=1;
    
    ans++;
  }
  
  cout<<ans<<endl;

  return 0;
}
accuracy: 1
time_ms: 3610
memory_kb: 31360
final_rank: 12

code_snippet: #include<bits/stdc++.h>
#define EPS (1e-8)
#define N_MAX 200005
using namespace std;
typedef double ll;

int N;
ll R,x[N_MAX],y[N_MAX];
bool used[N_MAX];

struct node{
  vector<ll> Point;
  int l,r;
  node(){}
  node(vector<ll> a){Point=a,l=r=-1;}
};

const int K=2;// K:テヲツャツ。テ・ツ?εヲツ閉ー
int D;// D:テ」ツ?敕」ツ?ョテヲツ卍づ」ツ?ォテ」ツつステ」ツδシテ」ツδ暗」ツ?凖」ツつ凝・ツ淞コテヲツコツ姪」ツ?ョテヲツャツ。テ・ツ??
vector<vector<ll> > P;// テ」ツ?敕」ツつ古」ツ?榲」ツつ古」ツ?ョティツヲツ?ァツエツ?」ツ?ッK+1テ・ツ??Kテ・ツ?凝」ツ?ョテヲツャツ。テ・ツ?ε」ツ?ョテァツ閉ェテ・ツ渉キテッツシツ凝、ツサツ佚」ツ?妥」ツ?淌」ツ??umber)
vector<node> G;

bool compare(const vector<ll> &A,const vector<ll> &B){return A[D]<B[D];}

int make_tree(int depth,int l,int r){
  if(l>r)return -1;
  D=depth%K;
  sort(P.begin()+l,P.begin()+r+1,compare);
  int m=(l+r)/2,res=G.size();
  G.push_back(node(P[m]));

  int vl=make_tree(depth+1,l,m-1);
  int vr=make_tree(depth+1,m+1,r);

  G[res].l=vl; G[res].r=vr;
  return res;
}

vector<int> num;// searchテ」ツ?ァティツヲツ凝」ツ?、テ」ツ?妥」ツつ凝」ツ?禿」ツ?ィテ」ツ?古」ツ?ァテ」ツ?催」ツ?淌ァツつケテ」ツ?ョnumberテ」ツつ津」ツ??」ツつ古」ツつ?

void search(int x,int depth,vector<ll> &L,vector<ll> &R){
  bool f=true;
  for(int i=0;i<K;i++)
    if(G[x].Point[i]<L[i]||R[i]<G[x].Point[i])f=false;

  if(f)num.push_back(G[x].Point[K]);

  D=depth%K;
  if(G[x].Point[D]<=R[D]&&G[x].r!=-1)search(G[x].r,depth+1,L,R);
  D=depth%K;
  if(L[D]<=G[x].Point[D]&&G[x].l!=-1)search(G[x].l,depth+1,L,R);
}

int main(){
  
  cin>>N>>R;
  
  P.resize(N);
  
  for(int i=0;i<N;i++){
    
    scanf("%lf %lf",&x[i],&y[i]);
    
    P[i].resize(K+1);
    
    P[i][K]=i;
    P[i][0]=x[i],P[i][1]=y[i];
  }
  
  make_tree(0,0,P.size()-1);
 
  int ans=0;
  for(int i=0;i<N;i++){
    
    if(used[i])continue;
    
    vector<ll> L2(K),R2(K);
    
    L2[0]=x[i]-R-EPS;
    R2[0]=x[i]+R+EPS;
    
    L2[1]=y[i]-R-EPS;
    R2[1]=y[i]+R+EPS;
    
    num.clear();
    
    search(0,0,L2,R2);
    
    for(int j=0;j<num.size();j++) used[num[j]]=1;
    
    ans++;
  }
  
  cout<<ans<<endl;

  return 0;
}
accuracy: 1
time_ms: 3560
memory_kb: 31472
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#define N_MAX 200005
using namespace std;
typedef double ll;

int N;
ll R,x[N_MAX],y[N_MAX];
bool used[N_MAX];

struct node{
  vector<ll> Point;
  int l,r;
  node(){}
  node(vector<ll> a){Point=a,l=r=-1;}
};

const int K=2;// K:テヲツャツ。テ・ツ?εヲツ閉ー
int D;// D:テ」ツ?敕」ツ?ョテヲツ卍づ」ツ?ォテ」ツつステ」ツδシテ」ツδ暗」ツ?凖」ツつ凝・ツ淞コテヲツコツ姪」ツ?ョテヲツャツ。テ・ツ??
vector<vector<ll> > P;// テ」ツ?敕」ツつ古」ツ?榲」ツつ古」ツ?ョティツヲツ?ァツエツ?」ツ?ッK+1テ・ツ??Kテ・ツ?凝」ツ?ョテヲツャツ。テ・ツ?ε」ツ?ョテァツ閉ェテ・ツ渉キテッツシツ凝、ツサツ佚」ツ?妥」ツ?淌」ツ??umber)
vector<node> G;

bool compare(vector<ll> A,vector<ll> B){return A[D]<B[D];}

int make_tree(int depth,int l,int r){
  if(l>r)return -1;
  D=depth%K;
  sort(P.begin()+l,P.begin()+r+1,compare);
  int m=(l+r)/2,res=G.size();
  G.push_back(node(P[m]));

  int vl=make_tree(depth+1,l,m-1);
  int vr=make_tree(depth+1,m+1,r);

  G[res].l=vl; G[res].r=vr;
  return res;
}

vector<int> num;// searchテ」ツ?ァティツヲツ凝」ツ?、テ」ツ?妥」ツつ凝」ツ?禿」ツ?ィテ」ツ?古」ツ?ァテ」ツ?催」ツ?淌ァツつケテ」ツ?ョnumberテ」ツつ津」ツ??」ツつ古」ツつ?

void search(int x,int depth,vector<ll> &L,vector<ll> &R){
  bool f=true;
  for(int i=0;i<K;i++)
    if(G[x].Point[i]<L[i]||R[i]<G[x].Point[i])f=false;

  if(f)num.push_back(G[x].Point[K]);

  D=depth%K;
  if(G[x].Point[D]<=R[D]&&G[x].r!=-1)search(G[x].r,depth+1,L,R);
  D=depth%K;
  if(L[D]<=G[x].Point[D]&&G[x].l!=-1)search(G[x].l,depth+1,L,R);
}

int main(){
  
  cin>>N>>R;
  
  P.resize(N);
  
  for(int i=0;i<N;i++){
    
    cin>>x[i]>>y[i];
    
    P[i].resize(K+1);
    
    P[i][K]=i;
    P[i][0]=x[i],P[i][1]=y[i];
  }
  
  make_tree(0,0,P.size()-1);
 
  int ans=0;
  for(int i=0;i<N;i++){
    
    if(used[i])continue;
    
    vector<ll> L2(K),R2(K);
    
    L2[0]=x[i]-R;
    R2[0]=x[i]+R;
    
    L2[1]=y[i]-R;
    R2[1]=y[i]+R;
    
    num.clear();
    
    search(0,0,L2,R2);
    
    for(int j=0;j<num.size();j++) used[num[j]]=1;
    ans++;
  }
  
  cout<<ans<<endl;

  return 0;
}
accuracy: 0.5303030303030303
time_ms: 2320
memory_kb: 33336
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<double,double> P;
typedef pair<int,int> PP;

double D(P a,P b) {
  return sqrt((a.F-b.F)*(a.F-b.F)+(a.S-b.S)*(a.S-b.S));
}

int p[222222],r[222222];
void init(){for(int i=0; i<222222; i++) p[i]=i,r[i]=0;}
int find(int x){return (p[x]==x)?x:(p[x]=find(p[x]));}
void unite(int x,int y) {
  x=find(x),y=find(y);
  if(x==y)return;
  if(r[x]<r[y])p[x]=y;
  else{p[y]=x;if(r[x]==r[y])r[x]++;}
}

int main() {
  init();
  int n;
  double d;
  cin >> n >> d;
  P a[n];
  for(int i=0; i<n; i++) cin >> a[i].F >> a[i].S;
  map<PP,int> m;
  for(int i=0; i<n; i++) {
    int x=floor(a[i].F/d),y=floor(a[i].S/d);
    for(int dx=-1; dx<2; dx++) {
      for(int dy=-1; dy<2; dy++) {
        if(m.count(PP(x+dx,y+dy))) unite(i,m[PP(x+dx,y+dy)]);
      }
    }
    m[PP(x,y)]=i;
  }
  set<int> s;
  for(int i=0; i<n; i++) s.insert(find(i));
  cout << s.size() << endl;
  return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 26976
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<double,double> P;

double D(P a,P b) {
  return sqrt((a.F-b.F)*(a.F-b.F)+(a.S-b.S)*(a.S-b.S));
}

int main() {
  int n;
  double r;
  cin >> n >> r;
  P a[n];
  for(int i=0; i<n; i++) cin >> a[i].F >> a[i].S;
  bool u[n];
  memset(u,0,sizeof(u));
  int ans=0;
  for(int i=0; i<n; i++) {
    if(u[i]) continue;
    u[i]=1;
    ans++;
    for(int j=i+1; j<n; j++) {
      if(u[j]) continue;
      if(D(a[i],a[j])<=r) u[j]=1;
    }
  }
  cout << ans << endl;
  return 0;
}
accuracy: 0.4090909090909091
time_ms: 180
memory_kb: 6536
final_rank: 16

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<tuple>
using namespace std;
class UnionFind {
private:
	unsigned size_; std::vector<unsigned> par, rank;
public:
	UnionFind() : size_(0), par(std::vector<unsigned>()), rank(std::vector<unsigned>()) {};
	UnionFind(unsigned size__) : size_(size__) {
		par.resize(size_); rank.resize(size_);
		for (unsigned i = 0; i < size_; i++) par[i] = i, rank[i] = 0;
	}
	unsigned size() { return size_; }
	unsigned root(unsigned x) { return par[x] == x ? x : par[x] = root(par[x]); }
	bool same(unsigned x, unsigned y) { return root(x) == root(y); }
	void unite(unsigned x, unsigned y) {
		x = root(x), y = root(y);
		if (x == y) return;
		if (rank[x] < rank[y]) par[x] = y;
		else if (rank[x] == rank[y]) par[y] = x, rank[x]++;
		else par[y] = x;
	}
	bool operator==(const UnionFind &u) { return par == u.par; }
	bool operator!=(const UnionFind &u) { return par != u.par; }
};
int n; long double x[200000], y[200000], R, r1 = 0.1145141919, r2 = 0.9868864999;
bool used[200000]; tuple<long double, long double, int>p[200000];
long double dst(long double px, long double py, long double qx, long double qy) {
	return sqrtl((px - qx)*(px - qx) + (py - qy)*(py - qy));
}
int main() {
	cin >> n >> R; int ans = 0;
	for (int i = 0; i < n; i++) {
		cin >> x[i] >> y[i];
		x[i] *= r2; y[i] *= r2;
		long double J1 = x[i], J2 = y[i]; J1 *= r1 / r2; J2 *= r1 / r2;
		x[i] -= J2; y[i] += J1; p[i] = make_tuple(x[i], y[i], i);
	}
	sort(p, p + n); UnionFind UF(n);
	for (int i = 0; i < n; i++) {
		if (used[i] == true)continue; ans++; used[i] = true;
		int pos1 = lower_bound(p, p + n, make_tuple(x[i] - R, y[i], i)) - p;
		int pos2 = lower_bound(p, p + n, make_tuple(x[i] + R, y[i], i)) - p;
		for (int j = pos1; j < pos2; j++) {
			if (dst(x[i], y[i], get<0>(p[j]), get<1>(p[j])) <= R*1.001l) {
				if (UF.same(i, get<2>(p[j])) == false) {
					UF.unite(i, get<2>(p[j])); used[get<2>(p[j])] = true;
				}
			}
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 20316
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<tuple>
using namespace std;
class UnionFind {
private:
	unsigned size_; std::vector<unsigned> par, rank;
public:
	UnionFind() : size_(0), par(std::vector<unsigned>()), rank(std::vector<unsigned>()) {};
	UnionFind(unsigned size__) : size_(size__) {
		par.resize(size_); rank.resize(size_);
		for (unsigned i = 0; i < size_; i++) par[i] = i, rank[i] = 0;
	}
	unsigned size() { return size_; }
	unsigned root(unsigned x) { return par[x] == x ? x : par[x] = root(par[x]); }
	bool same(unsigned x, unsigned y) { return root(x) == root(y); }
	void unite(unsigned x, unsigned y) {
		x = root(x), y = root(y);
		if (x == y) return;
		if (rank[x] < rank[y]) par[x] = y;
		else if (rank[x] == rank[y]) par[y] = x, rank[x]++;
		else par[y] = x;
	}
	bool operator==(const UnionFind &u) { return par == u.par; }
	bool operator!=(const UnionFind &u) { return par != u.par; }
};
int n; long double x[200000], y[200000], R, r1 = 0.1145141919, r2 = 0.9868864999;
bool used[200000]; tuple<long double, long double, int>p[200000];
long double dst(long double px, long double py, long double qx, long double qy) {
	return sqrtl((px - qx)*(px - qx) + (py - qy)*(py - qy));
}
int main() {
	cin >> n >> R; int ans = 0;
	for (int i = 0; i < n; i++) {
		cin >> x[i] >> y[i];
		x[i] *= r2; y[i] *= r2;
		long double J1 = x[i], J2 = y[i]; J1 *= r1 / r2; J2 *= r1 / r2;
		x[i] -= J1; y[i] += J2; p[i] = make_tuple(x[i], y[i], i);
	}
	sort(p, p + n); UnionFind UF(n);
	for (int i = 0; i < n; i++) {
		if (used[i] == true)continue; ans++; used[i] = true;
		int pos1 = lower_bound(p, p + n, make_tuple(x[i] - R, y[i], i)) - p;
		int pos2 = lower_bound(p, p + n, make_tuple(x[i] + R, y[i], i)) - p;
		for (int j = pos1; j < pos2; j++) {
			if (dst(x[i], y[i], get<0>(p[j]), get<1>(p[j])) <= R*1.001l) {
				if (UF.same(i, get<2>(p[j])) == false) {
					UF.unite(i, get<2>(p[j])); used[get<2>(p[j])] = true;
				}
			}
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 0.4090909090909091
time_ms: 220
memory_kb: 20288
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<tuple>
using namespace std;
class UnionFind {
private:
	unsigned size_; std::vector<unsigned> par, rank;
public:
	UnionFind() : size_(0), par(std::vector<unsigned>()), rank(std::vector<unsigned>()) {};
	UnionFind(unsigned size__) : size_(size__) {
		par.resize(size_); rank.resize(size_);
		for (unsigned i = 0; i < size_; i++) par[i] = i, rank[i] = 0;
	}
	unsigned size() { return size_; }
	unsigned root(unsigned x) { return par[x] == x ? x : par[x] = root(par[x]); }
	bool same(unsigned x, unsigned y) { return root(x) == root(y); }
	void unite(unsigned x, unsigned y) {
		x = root(x), y = root(y);
		if (x == y) return;
		if (rank[x] < rank[y]) par[x] = y;
		else if (rank[x] == rank[y]) par[y] = x, rank[x]++;
		else par[y] = x;
	}
	bool operator==(const UnionFind &u) { return par == u.par; }
	bool operator!=(const UnionFind &u) { return par != u.par; }
};
int n; long double x[200000], y[200000], R, r1 = 0.1145141919, r2 = 0.9868864999;
bool used[200000]; tuple<int, int, int>p[200000];
long double dst(long double px, long double py, long double qx, long double qy) {
	return sqrtl((px - qx)*(px - qx) + (py - qy)*(py - qy));
}
int main() {
	cin >> n >> R; int ans = 0;
	for (int i = 0; i < n; i++) {
		cin >> x[i] >> y[i];
		x[i] *= r2; y[i] *= r2;
		long double J1 = x[i], J2 = y[i]; J1 *= r1 / r2; J2 *= r1 / r2;
		x[i] -= J1; y[i] += J2; p[i] = make_tuple(x[i], y[i], i);
	}
	sort(p, p + n); UnionFind UF(n);
	for (int i = 0; i < n; i++) {
		if (used[i] == true)continue; ans++;
		int pos1 = lower_bound(p, p + n, make_tuple(x[i] - R, y[i], i)) - p;
		int pos2 = lower_bound(p, p + n, make_tuple(x[i] + R, y[i], i)) - p;
		for (int j = pos1; j < pos2; j++) {
			if (dst(x[i], y[i], get<0>(p[j]), get<1>(p[j])) <= R) {
				if (UF.same(i, get<2>(p[j])) == false) {
					UF.unite(i, get<2>(p[j])); used[get<2>(p[j])] = true;
				}
			}
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 0.19696969696969696
time_ms: 200
memory_kb: 13156
final_rank: 20

code_snippet: #include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n; double r, x, y, cx[200009], cy[200009]; pair<double, double> p[200009]; bool vis[200009];
int main() {
	scanf("%d%lf", &n, &r);
	for (int i = 0; i < n; i++) {
		scanf("%lf%lf", &x, &y);
		double ex = x * 0.28 - y * 0.96;
		double ey = x * 0.96 + y * 0.28;
		p[i] = make_pair(ex, ey);
	}
	sort(p, p + n);
	for (int i = 0; i < n; i++) cx[i] = p[i].first, cy[i] = p[i].second;
	int ret = 0;
	for (int i = 0; i < n; i++) {
		if (vis[i]) continue;
		int ptl = lower_bound(cx, cx + n, cx[i] - r - 1.0e-4) - cx;
		int ptr = lower_bound(cx, cx + n, cx[i] + r + 1.0e-4) - cx;
		for (int j = ptl; j < ptr; j++) {
			double dx = cx[i] - cx[j];
			double dy = cy[i] - cy[j];
			if (dx * dx + dy * dy <= 2.0 * r * r) vis[j] = true;
		}
		ret++;
	}
	cout << ret << endl;
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 9724
final_rank: 1

code_snippet: #include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n; double r, x, y, cx[200009], cy[200009]; pair<double, double> p[200009]; bool vis[200009];
int main() {
	scanf("%d%lf", &n, &r);
	for (int i = 0; i < n; i++) {
		scanf("%lf%lf", &x, &y);
		double ex = x * 0.28 - y * 0.96;
		double ey = x * 0.96 + y * 0.28;
		p[i] = make_pair(ex, ey);
	}
	sort(p, p + n);
	for (int i = 0; i < n; i++) cx[i] = p[i].first, cy[i] = p[i].second;
	int ret = 0;
	for (int i = 0; i < n; i++) {
		if (vis[i]) continue;
		int ptl = lower_bound(cx, cx + n, cx[i] - r - 1.0e-6) - cx;
		int ptr = lower_bound(cx, cx + n, cx[i] + r + 1.0e-6) - cx;
		for (int j = ptl; j < ptr; j++) {
			double dx = cx[i] - cx[j];
			double dy = cy[i] - cy[j];
			if (dx * dx + dy * dy <= r * r) vis[j] = true;
		}
		ret++;
	}
	cout << ret << endl;
	return 0;
}
accuracy: 0.4090909090909091
time_ms: 80
memory_kb: 9664
final_rank: 17