#include<bits/stdc++.h> using namespace std; struct first { double a,val; }; double det(first &a,first &b){return (a.a*b.val) - (a.val*b.a);} bool operator<(first a,first b){return det(a,b) < 0;} bool bin_search(int l, int r,double prefix_sums_1[], double prefix_sums_2[],vector<first> &vec,first value,double t,double h) { int s = (l+r)/2;/* cout << "czy " << s << " sie z nim przecina " <<endl; if(l>r) return false; doublea_s = (vec[s].val)/vec[s].a; doublea_val = (value.val)/value.a; doubleb_s = prefix_sums_1[s]-(a_s*prefix_sums_2[s]); doubleb_val = t - (a_val*h); if(a_s==a_val && b_s==b_val) return true; if(a_s==a_val) return bin_search(l+1,r,prefix_sums_1,prefix_sums_2,vec,value,t,h); double x = (b_val - b_s)/(a_s-a_val); cout << "wspl rand " << a_s << " " << b_s<<endl; cout << "wspl kon " << a_val << " " << b_val<<endl; cout << "przecinaja sie w punkcie " << x <<endl; if(x<prefix_sums_2[s] || x <= h || t > a_s*x + b_s) return bin_search(l+1,r,prefix_sums_1,prefix_sums_2,vec,value,t,h); if(x>prefix_sums_2[s+1]) return bin_search(l,r-1,prefix_sums_1,prefix_sums_2,vec,value,t,h); return true; */ for(int k=0;k<=r;k++) { s = k; double a_s = (vec[s].val)/vec[s].a; double a_val = (value.val)/value.a; double b_s = prefix_sums_1[s]-(a_s*prefix_sums_2[s]); double b_val = t - (a_val*h); if(t==prefix_sums_1[s+1]) return true; if(a_s>=a_val) continue; double x = (b_val - b_s)/(a_s-a_val); // cout << "wspl rand " << a_s << " " << b_s<<endl; // cout << "wspl kon " << a_val << " " << b_val<<endl; // cout << "przecinaja sie w punkcie " << x <<endl; if( x >= prefix_sums_2[s] && x<=prefix_sums_2[s+1] && x>=h) return true; } return false; } int main() { ios_base::sync_with_stdio(0); int z; cin >> z; while(z--) { int n; cin >> n; vector<first> vec_1(n); vector<first> vec_2(n); for(int k=0;k<n;k++) { double a,b,c; cin >> a >> b>> c; vec_1[k].a = a; vec_1[k].val = a*b; vec_2[k].a = a; vec_2[k].val = a*c; } // cout << min_1 << " " << min_2 << " " << max_1 << " "<< max_2 <<endl; sort(vec_1.begin(),vec_1.end()); sort(vec_2.begin(),vec_2.end()); /*cout << "sort ciagu 1"<<endl; for(int k=0;k<n;k++) { cout << vec_1[k].a << " " << vec_1[k].val <<endl; } cout << "sort ciagu 2"<<endl; for(int k=0;k<n;k++) { cout << vec_2[k].a << " " << vec_2[k].val <<endl; }*/ double prefix_sums_1[n+1]; double prefix_sums_2[n+1]; prefix_sums_2[0]=0; prefix_sums_1[0]=0; for(int k=0;k<n;k++) { prefix_sums_1[k+1] = prefix_sums_1[k] + vec_1[k].val; prefix_sums_2[k+1] = prefix_sums_2[k] + vec_1[k].a; } bool done = false; double t = 0; double h = 0; for(int k=0;k<n;k++) { // cout << "sprawdzam czy sie przecinaja " << k <<endl; if(!bin_search(0,n-1,prefix_sums_1,prefix_sums_2,vec_1,vec_2[k],t,h)) { done = true; break; } t+=vec_2[k].val; h+=vec_2[k].a; } if(done) cout << "NIE"<<endl; else cout << "TAK"<<endl; } }
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 109 110 111 112 113 114 115 116 | #include<bits/stdc++.h> using namespace std; struct first { double a,val; }; double det(first &a,first &b){return (a.a*b.val) - (a.val*b.a);} bool operator<(first a,first b){return det(a,b) < 0;} bool bin_search(int l, int r,double prefix_sums_1[], double prefix_sums_2[],vector<first> &vec,first value,double t,double h) { int s = (l+r)/2;/* cout << "czy " << s << " sie z nim przecina " <<endl; if(l>r) return false; doublea_s = (vec[s].val)/vec[s].a; doublea_val = (value.val)/value.a; doubleb_s = prefix_sums_1[s]-(a_s*prefix_sums_2[s]); doubleb_val = t - (a_val*h); if(a_s==a_val && b_s==b_val) return true; if(a_s==a_val) return bin_search(l+1,r,prefix_sums_1,prefix_sums_2,vec,value,t,h); double x = (b_val - b_s)/(a_s-a_val); cout << "wspl rand " << a_s << " " << b_s<<endl; cout << "wspl kon " << a_val << " " << b_val<<endl; cout << "przecinaja sie w punkcie " << x <<endl; if(x<prefix_sums_2[s] || x <= h || t > a_s*x + b_s) return bin_search(l+1,r,prefix_sums_1,prefix_sums_2,vec,value,t,h); if(x>prefix_sums_2[s+1]) return bin_search(l,r-1,prefix_sums_1,prefix_sums_2,vec,value,t,h); return true; */ for(int k=0;k<=r;k++) { s = k; double a_s = (vec[s].val)/vec[s].a; double a_val = (value.val)/value.a; double b_s = prefix_sums_1[s]-(a_s*prefix_sums_2[s]); double b_val = t - (a_val*h); if(t==prefix_sums_1[s+1]) return true; if(a_s>=a_val) continue; double x = (b_val - b_s)/(a_s-a_val); // cout << "wspl rand " << a_s << " " << b_s<<endl; // cout << "wspl kon " << a_val << " " << b_val<<endl; // cout << "przecinaja sie w punkcie " << x <<endl; if( x >= prefix_sums_2[s] && x<=prefix_sums_2[s+1] && x>=h) return true; } return false; } int main() { ios_base::sync_with_stdio(0); int z; cin >> z; while(z--) { int n; cin >> n; vector<first> vec_1(n); vector<first> vec_2(n); for(int k=0;k<n;k++) { double a,b,c; cin >> a >> b>> c; vec_1[k].a = a; vec_1[k].val = a*b; vec_2[k].a = a; vec_2[k].val = a*c; } // cout << min_1 << " " << min_2 << " " << max_1 << " "<< max_2 <<endl; sort(vec_1.begin(),vec_1.end()); sort(vec_2.begin(),vec_2.end()); /*cout << "sort ciagu 1"<<endl; for(int k=0;k<n;k++) { cout << vec_1[k].a << " " << vec_1[k].val <<endl; } cout << "sort ciagu 2"<<endl; for(int k=0;k<n;k++) { cout << vec_2[k].a << " " << vec_2[k].val <<endl; }*/ double prefix_sums_1[n+1]; double prefix_sums_2[n+1]; prefix_sums_2[0]=0; prefix_sums_1[0]=0; for(int k=0;k<n;k++) { prefix_sums_1[k+1] = prefix_sums_1[k] + vec_1[k].val; prefix_sums_2[k+1] = prefix_sums_2[k] + vec_1[k].a; } bool done = false; double t = 0; double h = 0; for(int k=0;k<n;k++) { // cout << "sprawdzam czy sie przecinaja " << k <<endl; if(!bin_search(0,n-1,prefix_sums_1,prefix_sums_2,vec_1,vec_2[k],t,h)) { done = true; break; } t+=vec_2[k].val; h+=vec_2[k].a; } if(done) cout << "NIE"<<endl; else cout << "TAK"<<endl; } } |