#include <cstdio> #include <vector> #include <algorithm> using namespace std; int tree[4194304], from[4194304], to[4194304]; int get_max_node(int node, int a, int b) { if (a<=from[node] && to[node] <= b) return tree[node]; if (b<from[node] || a>to[node]) return 0; int l = 2*node; //printf("%d %d\n", to[l], from[l+1]); if (b<from[l] || a>to[l]) return get_max_node(l+1, a, b); else if (b<from[l+1] || a>to[l+1]) return get_max_node(l, a, b); else return max(get_max_node(l, a,to[l]), get_max_node(l+1,from[l+1], b)); } int get_max(int a, int b) { return get_max_node(1, a, b); } int main() { int t; scanf("%d", &t); while (t--) { long long n, w; vector< pair<int, int> > v; scanf("%lld %lld", &n, &w); int heights[n+2]; for (int i=0;i<n;i++){ int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); int h = y2>y1 ? y2-y1 : y1-y2; v.push_back(make_pair(min(x1, x2), i)); heights[i] = h; } sort(v.begin(), v.end()); int mapa[n+2]; for (int i=0;i<n;i++) mapa[v[i].second] = i+1; v.clear(); for (int i=0;i<n;i++){ int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); //int h = y2>y1 ? y2-y1 : y1-y2; v.push_back(make_pair(min(x1,x2), i)); } sort(v.begin(), v.end()); int koniec[n+2]; for (int i=0;i<n;i++) koniec[i+1] = mapa[v[i].second]; //for (int i=0;i<n;i++) printf ("%d (%d): %d\n", i, heights[i], mapa[i]); //for (int i=0;i<n;i++) printf("%d ", mapa[i]); printf("\n"); //for (int i=1;i<=n;i++) printf("%d ", koniec[i]); printf("\n"); int size = 1; int s = 1; int tmp = n; while (tmp>1) { tmp = tmp/2+ (tmp%2); s *= 2; size += s; } int org_size = size; size++; for (int i=0;i<size+5;i++) {tree[i]=0; from[i]=1; to[i]=n;} size /= 2; int pozycja[n+4]; for (int i=0;i<n;i++) pozycja[mapa[i]] = i; //printf("Pozycja: ");for (int i=1;i<=n;i++) printf("%d ", pozycja[i]); printf("\n"); for (int i=0;i<n;i++) { tree[size+i] = heights[pozycja[i+1]]; to[size+i] = from[size+i] = i+1; } while (size >0){ size /= 2; s /= 2; for (int i=0;i<s;i++) {tree[size+i] = max(tree[2*(size+i)], tree[2*(size+i)+1]); //printf("%d = max(%d, %d)\n",size+i, 2*(size+i), 2*(size+i)+1); from[size+i] = from[2*(size+i)]; to[size+i] = to[2*(size+i)+1]; //printf("%d ~ [%d, %d]\n",size+i, from[size+i], to[size+i]); } } bool result = true; for (int i=n;i>0;i--) { // sprawdzić if (koniec[i] != n && get_max(koniec[i]+1, n) + heights[pozycja[koniec[i]]] > w) {result = false; //printf ("NIE: %d (%d)\n", koniec[i], get_max(koniec[i]+1, n)); break;} // usunąć koniec[i] size = (org_size + 1)/2; int pos = size+koniec[i]-1; tree[pos] = 0; pos /=2; while(pos>0) { tree[pos] = max(tree[2*pos], tree[2*pos+1]); pos /=2; } } printf("%s\n", result ? "TAK" : "NIE"); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #include <cstdio> #include <vector> #include <algorithm> using namespace std; int tree[4194304], from[4194304], to[4194304]; int get_max_node(int node, int a, int b) { if (a<=from[node] && to[node] <= b) return tree[node]; if (b<from[node] || a>to[node]) return 0; int l = 2*node; //printf("%d %d\n", to[l], from[l+1]); if (b<from[l] || a>to[l]) return get_max_node(l+1, a, b); else if (b<from[l+1] || a>to[l+1]) return get_max_node(l, a, b); else return max(get_max_node(l, a,to[l]), get_max_node(l+1,from[l+1], b)); } int get_max(int a, int b) { return get_max_node(1, a, b); } int main() { int t; scanf("%d", &t); while (t--) { long long n, w; vector< pair<int, int> > v; scanf("%lld %lld", &n, &w); int heights[n+2]; for (int i=0;i<n;i++){ int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); int h = y2>y1 ? y2-y1 : y1-y2; v.push_back(make_pair(min(x1, x2), i)); heights[i] = h; } sort(v.begin(), v.end()); int mapa[n+2]; for (int i=0;i<n;i++) mapa[v[i].second] = i+1; v.clear(); for (int i=0;i<n;i++){ int x1, x2, y1, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); //int h = y2>y1 ? y2-y1 : y1-y2; v.push_back(make_pair(min(x1,x2), i)); } sort(v.begin(), v.end()); int koniec[n+2]; for (int i=0;i<n;i++) koniec[i+1] = mapa[v[i].second]; //for (int i=0;i<n;i++) printf ("%d (%d): %d\n", i, heights[i], mapa[i]); //for (int i=0;i<n;i++) printf("%d ", mapa[i]); printf("\n"); //for (int i=1;i<=n;i++) printf("%d ", koniec[i]); printf("\n"); int size = 1; int s = 1; int tmp = n; while (tmp>1) { tmp = tmp/2+ (tmp%2); s *= 2; size += s; } int org_size = size; size++; for (int i=0;i<size+5;i++) {tree[i]=0; from[i]=1; to[i]=n;} size /= 2; int pozycja[n+4]; for (int i=0;i<n;i++) pozycja[mapa[i]] = i; //printf("Pozycja: ");for (int i=1;i<=n;i++) printf("%d ", pozycja[i]); printf("\n"); for (int i=0;i<n;i++) { tree[size+i] = heights[pozycja[i+1]]; to[size+i] = from[size+i] = i+1; } while (size >0){ size /= 2; s /= 2; for (int i=0;i<s;i++) {tree[size+i] = max(tree[2*(size+i)], tree[2*(size+i)+1]); //printf("%d = max(%d, %d)\n",size+i, 2*(size+i), 2*(size+i)+1); from[size+i] = from[2*(size+i)]; to[size+i] = to[2*(size+i)+1]; //printf("%d ~ [%d, %d]\n",size+i, from[size+i], to[size+i]); } } bool result = true; for (int i=n;i>0;i--) { // sprawdzić if (koniec[i] != n && get_max(koniec[i]+1, n) + heights[pozycja[koniec[i]]] > w) {result = false; //printf ("NIE: %d (%d)\n", koniec[i], get_max(koniec[i]+1, n)); break;} // usunąć koniec[i] size = (org_size + 1)/2; int pos = size+koniec[i]-1; tree[pos] = 0; pos /=2; while(pos>0) { tree[pos] = max(tree[2*pos], tree[2*pos+1]); pos /=2; } } printf("%s\n", result ? "TAK" : "NIE"); } return 0; } |