呵呵,我以为你要这个映射关系的原理呢。你曹哥还是那么话少


重剑无锋,大巧不工
#include<stdio.h> #define M 100 int cal(int map[][M], int n) { int x[M] = {}, lx[M], mx[M]; int y[M] = {}, ly[M], my[M]; int c = 0, lxn, lyn, i, j, k, t; for(c = i = 0; i < n; i++) { if(x[i]) continue; for(j = 0; j < n; j++) mx[j] = my[j] = 0; mx[i] = 1; lx[0] = i; lxn = 1; lyn = 0; for(k = j = 0; j < lxn; j++) { for(t = 0; t < n; t++) { if(!map[lx[j]][t] || my[t]) continue; if(y[t]){ my[t] = 1; ly[lyn++] = t;} else{ x[i] = 1; y[t] = 1; c++; break;} } if(t != n) break; for(; k < lyn; k++) for(t = 0; t < n; t++) if(x[t] && map[t][ly[k]] && !mx[t]) { lx[lxn++] = t; mx[t] = 1; } } } return c; } int main() { int map[M][M], x[M], y[M], s[M], e[M]; int t, n, i, j, d; for(scanf("%d", &t); t--; printf("%d\n", cal(map, n))) { for(scanf("%d", &n), i = 0; i < n; s[i] *= s[i], e[i] *= e[i], i++) scanf("%d%d%d%d", &x[i], &y[i], &s[i], &e[i]); for(i = 0; i < n; i++) for(j = 0; j < n; j++) map[i][j] = (d = (d = x[i] - x[j]) * d + (d = y[i] - y[j]) * d) >= s[i] && d <= e[i]; } return 0; }
#include<stdio.h> long long cal(int W, int H, int L1, int L2) { long long c; int i, j, di, d, t, t1, t2; c = L1 == 1 ? W * H * 2 + W + H : 0; L1 *= L1; L2 *= L2; for(di = i = 1; i <= W; di += (++i << 1) - 1) for(d = di + (j = 1); j <= H && d <= L2; d += (++j << 1) - 1) { if(d < L1) continue; for(t1 = i, t2 = j; t = t1 % t2; t1 = t2, t2 = t); if(t2 == 1) c += (W - i + 1) * (H - j + 1) << 1; } return c; } int main() { int W, H, L1, L2; scanf("%d%d%d%d", &W, &H, &L1, &L2); printf("%lld\n", cal(W, H, L1, L2)); return 0; }
#include<stdio.h> #define MAX_RANGE 500000 #define MAX_FN 7 struct { int L, R; int max[MAX_FN]; int min[MAX_FN]; int il, ir; } ST[MAX_RANGE * 2]; int FL, FR, K; void build_tree(int L, int R, int root) { static int ip = MAX_RANGE + 1; int i; ST[root].L = L; ST[root].R = R; i = (L + R) >> 1; if(i == L) ST[root].il = L; else build_tree(L, i, ST[root].il = ip++); if(i + 1 == R) ST[root].ir = R; else build_tree(i + 1, R, ST[root].ir = ip++); for(i = 0; i < MAX_FN; i++) { ST[root].max[i] = ST[ST[root].il].max[i] > ST[ST[root].ir].max[i] ? ST[ST[root].il].max[i] : ST[ST[root].ir].max[i]; ST[root].min[i] = ST[ST[root].il].min[i] < ST[ST[root].ir].min[i] ? ST[ST[root].il].min[i] : ST[ST[root].ir].min[i]; } } void init() { int i, j, t; ST[1].L = ST[1].R = 1; for(i = 0; i < MAX_FN; i++) ST[1].max[i] = ST[1].min[i] = 2; for(i = 2; i <= MAX_RANGE; i++) { ST[i].L = ST[i].R = i; if(!ST[i].il) for(j = i + i; j <= MAX_RANGE; ST[j].il++, j += i) ST[j].max[ST[j].il] = ST[j].min[ST[j].il] = i + j; for(t = i + i, j = ST[i].il; j < MAX_FN; j++) ST[i].max[j] = ST[i].min[j] = t; } build_tree(1, MAX_RANGE, 0); } void search(int L, int R, int root) { if(L > ST[root].R || R < ST[root].L) return; if(L <= ST[root].L && R >= ST[root].R) { if(FL > ST[root].min[K]) FL = ST[root].min[K]; if(FR < ST[root].max[K]) FR = ST[root].max[K]; return; } if(L < ST[root].L) L = ST[root].L; if(R > ST[root].R) R = ST[root].R; search(L, R, ST[root].il); search(L, R, ST[root].ir); } void output(int L, int R) { FL = MAX_RANGE * 2; FR = 1; K = K > MAX_FN ? MAX_FN - 1 : K - 1; search(L, R, 0); printf("%d %d\n", FL, FR); } int main() { int n, Li, Ri; init(); for(scanf("%d", &n); n--; output(Li, Ri)) scanf("%d%d%d", &Li, &Ri, &K); return 0; }