#include #define ll long long using namespace std; char *pos, BUFFER[1600096]; inline int getnum() { char C; while ((C = *pos++) < '0'); int RET = C -= '0'; while ((C = *pos++) >= '0') RET = 10 * RET + C - '0'; return RET; } mt19937_64 rng; clock_t END; int N, R; ll DOUBLE, DIST, MANHATTAN; struct XY { int x; int y; int i; }C[100096]; struct DIRECT { int x; int y; }D[100096]; int PERM[100096]; ll DISTANCE[2][100096]; struct SHAPE { int s; int i; }SHAPES[5096]; bool COLLISION[5006][5006]; int KC, K; int CIRCLES[100096], CIRCLESFINAL[100096]; inline void Endtime() { END = 3.8 * CLOCKS_PER_SEC; return; } inline ll sqr(ll e){return e * e;} inline ll mul(ll a, ll b){return a * b;} inline void PrintPERM() { printf("PERM:"); for(int i = 0; i <= N; i++) printf(" %d", PERM[i]); printf("\n"); return; } inline void Clear() { KC = 0; return; } inline void Check() { if(KC > K) { K = KC; swap(CIRCLES, CIRCLESFINAL); } return; } inline bool Collision(int i, int j) { return ((sqr(D[i].x - D[j].x) + sqr(D[i].y - D[j].y)) < DIST); } inline bool compMANHATTAN(int i, int j) { return DISTANCE[0][i] < DISTANCE[0][j]; } inline bool compEUCLID(int i, int j) { return DISTANCE[0][i] < DISTANCE[0][j]; } inline bool compCLOCKWISE(int i, int j) { if((DISTANCE[0][i] / DIST) != (DISTANCE[0][j] / DIST)) return (DISTANCE[0][i] / DIST) < (DISTANCE[0][j] / DIST); if((D[i].x > D[0].x) && (D[j].x > D[0].x)) return (mul(D[i].x - D[0].x, D[j].y - D[0].y) - mul(D[j].x - D[0].x, D[i].y - D[0].y)) > 0; if((D[i].x < D[0].x) && (D[j].x < D[0].x)) return (mul(D[i].x - D[0].x, D[j].y - D[0].y) - mul(D[j].x - D[0].x, D[i].y - D[0].y)) < 0; return (D[i].x > D[0].x) && (D[j].x < D[0].x); } inline void MakePermutation() { for(int i = N; i; i--) PERM[i] = i; return; } inline void MakeManhattan() { for(int i = 1; i <= N; i++) DISTANCE[0][i] = abs(D[i].x - D[0].x) + abs(D[i].y - D[0].y); return; } inline void MakeEuclid() { for(int i = 1; i <= N; i++) DISTANCE[0][i] = sqr(D[i].x - D[0].x) + sqr(D[i].y - D[0].y); for(int i = 1; i <= N; i++) DISTANCE[1][i] = sqrt(DISTANCE[0][i]) / DOUBLE; } inline void RandomFitting() { for(int i = 1; i <= N; i++) { for(int j = KC; j; j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; } inline void ReverseRandomFitting() { for(int i = N; i; i--) { for(int j = KC; j; j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; } inline void ManhattanFitting() { for(int i = 1; i <= N; i++) { for(int j = KC; j && (abs(DISTANCE[0][PERM[i]] - DISTANCE[0][CIRCLES[j]]) <= MANHATTAN); j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; } inline void ReverseManhattanFitting() { for(int i = N; i; i--) { for(int j = KC; j && (abs(DISTANCE[0][PERM[i]] - DISTANCE[0][CIRCLES[j]]) <= MANHATTAN); j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; return; } inline void EuclidFitting() { for(int i = 1; i <= N; i++) { for(int j = KC; j && (abs(DISTANCE[1][PERM[i]] - DISTANCE[1][CIRCLES[j]]) < 2); j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; } inline void ReverseEuclidFitting() { for(int i = N; i; i--) { for(int j = KC; j && (abs(DISTANCE[1][PERM[i]] - DISTANCE[1][CIRCLES[j]]) < 2); j--) if(Collision(PERM[i], CIRCLES[j])) goto F; CIRCLES[++KC] = PERM[i]; F:; } Check(); Clear(); return; } inline void RandomBothWays() { RandomFitting(); ReverseRandomFitting(); return; } inline void EuclidBothWays() { EuclidFitting(); ReverseEuclidFitting(); return; } inline void ManhattanBothWays() { ManhattanFitting(); ReverseManhattanFitting(); return; } inline void PermutationBrute() { if(N > 100) return; RandomBothWays(); while(clock() < END) { shuffle(PERM + 1, PERM + N + 1, rng); RandomBothWays(); } return; } inline void Manhattan() { sort(PERM + 1, PERM + N + 1, compMANHATTAN); ManhattanBothWays(); return; } inline void Euclid() { sort(PERM + 1, PERM + N + 1, compEUCLID); EuclidBothWays(); return; } inline void Clockwise() { sort(PERM + 1, PERM + N + 1, compCLOCKWISE); EuclidBothWays(); return; } inline void RandomPointBrute() { if(N <= 100) return; while(true) { D[0] = D[rng() % N + 1]; MakeManhattan(); Manhattan(); if(clock() >= END) return; MakeEuclid(); Euclid(); if(clock() >= END) return; Clockwise(); if(clock() >= END) return; } return; } inline void Input() { freopen("mars.in", "r", stdin); fread(BUFFER, 1, 1600096, stdin); pos = BUFFER; N = getnum(); R = getnum(); DOUBLE = R << 1; MANHATTAN = DOUBLE << 1; DIST = sqr(DOUBLE); for(int i = 1; i <= N; i++) { C[i].x = getnum(); C[i].y = getnum(); C[i].i = i; D[i].x = C[i].x; D[i].y = C[i].y; } return; } inline void Output() { freopen("mars.out", "w", stdout); printf("%d\n", K); for(int i = 1; i <= K; i++) { printf("%d ", CIRCLESFINAL[i]); } printf("\n"); return; } int main() { rng.seed(31111); Input(); Endtime(); MakePermutation(); RandomPointBrute(); PermutationBrute(); printf("SCORE:\t\t%d\n", K); Output(); return 0; }