結果

問題 No.2173 Nightcord
ユーザー 👑 rin204rin204
提出日時 2022-12-25 01:51:30
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
RE  
実行時間 -
コード長 9,283 bytes
コンパイル時間 3,130 ms
コンパイル使用メモリ 240,504 KB
実行使用メモリ 382,080 KB
最終ジャッジ日時 2024-04-29 07:36:18
合計ジャッジ時間 7,673 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 RE -
testcase_01 RE -
testcase_02 AC 2 ms
5,376 KB
testcase_03 TLE -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
testcase_41 -- -
testcase_42 -- -
testcase_43 -- -
testcase_44 -- -
testcase_45 -- -
testcase_46 -- -
testcase_47 -- -
testcase_48 -- -
testcase_49 -- -
testcase_50 -- -
testcase_51 -- -
testcase_52 -- -
testcase_53 -- -
testcase_54 -- -
testcase_55 -- -
testcase_56 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 1 "A.cpp"
/*
考慮する必要のあるケース

k = 3 の場合
- 一直線上に R B R みたいに並んでいたら YES
- それ以外は NO

k >= 4 の場合
- ある点が,もう一方の色の凸包内部にあったら YES
	- 一直線上のケースは内部判定の時に境界をOKにすればいける
- 2色の点を2つずつ選んだ時に,2つの線分が交差したらYES
	- 良い感じに平行移動して偏角ソートすればできるはず...

k >= 5 の場合で,k = 4 の良い星座の部分集合を含まないケースって存在するのか...?

*/
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl "\n"

void print(){
	cout << '\n';
}

template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
	cout << head;
	if (sizeof...(Tail)) cout << ' ';
  	print(forward<Tail>(tail)...);
}

template<typename T>
void print(vector<T> &A){
	int n = A.size();
	for(int i = 0; i < n; i++){
		cout << A[i];
		if(i == n - 1) cout << '\n';
		else cout << ' ';
	}
}

template<typename T, typename S>
void prisep(vector<T> &A, S sep){
	int n = A.size();
	for(int i = 0; i < n; i++){
		cout << A[i];
		if(i == n - 1) cout << '\n';
		else cout << sep;
	}
}

template<typename T>
void print(vector<vector<T>> &A){
	for(auto &row: A) print(row);
}

#line 2 "Library/C++/geometry/Point.hpp"

struct Point{
    long long x;
    long long y;
    Point(){}
    Point(long long x, long long y) : x(x), y(y) {}

    int area(){
        if(y < 0){
            if(x < 0) return 1;
            else return 2;
        }
        else{
            if(x >= 0) return 3;
            else return 4;
        }
    }

    bool operator<(Point& rhs){
        int ap = area();
        int aq = rhs.area();
        if(ap == aq){
            if (x == 0 && y == 0) return true;
            return x * rhs.y > rhs.x * y;
        }
        else{
            return ap < aq;
        }
    }
};
#line 3 "Library/C++/geometry/cross3.hpp"

long long cross3(Point &a, Point &b, Point &c){
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}
#line 4 "Library/C++/geometry/convexHull.hpp"

vector<Point> convexHull(vector<Point> P, bool multi=true){
    sort(P.begin(), P.end(), [](Point &l, Point &r){
        if(l.x == r.x) return l.y < r.y;
        return l.x < r.x;
    });
    vector<Point> Q;
    int n = P.size();
    if(multi){
        for(auto p:P){
            while(Q.size() > 1 && cross3(Q[Q.size() - 1], Q[Q.size() - 2], p) > 0){
                Q.pop_back();
            }
            Q.push_back(p);
        }
        int t = Q.size();
        for(int i = n - 2; i >= 0; i--){
            Point p = P[i];
            while(Q.size() > t && cross3(Q[Q.size() - 1], Q[Q.size() - 2], p) > 0){
                Q.pop_back();
            }
            Q.push_back(p);
        }
    }
    else{
        for(auto p:P){
            while(Q.size() > 1 && cross3(Q[Q.size() - 1], Q[Q.size() - 2], p) >= 0){
                Q.pop_back();
            }
            Q.push_back(p);
        }
        int t = Q.size();
        for(int i = n - 2; i >= 0; i--){
            Point p = P[i];
            while(Q.size() > t && cross3(Q[Q.size() - 1], Q[Q.size() - 2], p) >= 0){
                Q.pop_back();
            }
            Q.push_back(p);
        }
    }
    Q.pop_back();
    return Q;
}
#line 62 "A.cpp"

void solve(){
    int n, k;
	cin >> n >> k;
	vector<Point> R, B;
	int x, y, c;
	for(int i = 0; i < n; i++){
		cin >> x >> y >> c;
		if(c == 1) R.push_back({x, y});
		else B.push_back({x, y});
	}
	if(R.size() == 0 || B.size() == 0){
		print("No");
		return;
	}
	if(R.size() > B.size()) swap(R, B);
	int lr = R.size();
	int lb = B.size();

	if(k == 3){
		map<pair<pair<ll, ll>, pair<ll, ll>>, set<pair<ll, int>>> mp;
		for(int i = 0; i < lr; i++){
			for(int j = i + 1; j < lr; j++){
				ll dx = R[j].x - R[i].x;
				ll dy = R[j].y - R[i].y;
				ll g = gcd(dx, dy);
				dx /= g;
				dy /= g;
				if(dx < 0){
					dx *= -1;
					dy *= -1;
				}
				else if(dx == 0 && dy < 0){
					dy *= -1;
				}
				ll xx = R[i].x;
				ll yy = R[i].y;
				ll d = xx / dx;
				xx -= d * dx;
				yy -= d * dy;
				if(xx < 0){
					xx += dx;
					yy += dy;
				}
				if(dx != 0){
					mp[{{dx, dy}, {xx, yy}}].insert({R[i].x, 0});
					mp[{{dx, dy}, {xx, yy}}].insert({R[j].x, 0});
				}
				else{
					mp[{{dx, dy}, {xx, yy}}].insert({R[i].y, 0});
					mp[{{dx, dy}, {xx, yy}}].insert({R[j].y, 0});
				}
			}
		}

		for(int i = 0; i < lb; i++){
			for(int j = i + 1; j < lb; j++){
				ll dx = B[j].x - B[i].x;
				ll dy = B[j].y - B[i].y;
				ll g = gcd(dx, dy);
				dx /= g;
				dy /= g;
				if(dx < 0){
					dx *= -1;
					dy *= -1;
				}
				else if(dx == 0 && dy < 0){
					dy *= -1;
				}
				ll xx = B[i].x;
				ll yy = B[i].y;
				ll d = xx / dx;
				xx -= d * dx;
				yy -= d * dy;
				if(xx < 0){
					xx += dx;
					yy += dy;
				}
				if(dx != 0){
					mp[{{dx, dy}, {xx, yy}}].insert({B[i].x, 1});
					mp[{{dx, dy}, {xx, yy}}].insert({B[j].x, 1});
				}
				else{
					mp[{{dx, dy}, {xx, yy}}].insert({B[i].y, 1});
					mp[{{dx, dy}, {xx, yy}}].insert({B[j].y, 1});
				}
			}
		}	

		for(int i = 0; i < lr; i++){
			for(int j = 0; j < lb; j++){
				ll dx = B[j].x - R[i].x;
				ll dy = B[j].y - R[i].y;
				ll g = gcd(dx, dy);
				dx /= g;
				dy /= g;
				if(dx < 0){
					dx *= -1;
					dy *= -1;
				}
				else if(dx == 0 && dy < 0){
					dy *= -1;
				}
				ll xx = R[i].x;
				ll yy = R[i].y;
				ll d = xx / dx;
				xx -= d * dx;
				yy -= d * dy;
				if(xx < 0){
					xx += dx;
					yy += dy;
				}
				if(dx != 0){
					mp[{{dx, dy}, {xx, yy}}].insert({R[i].x, 0});
					mp[{{dx, dy}, {xx, yy}}].insert({B[j].x, 1});
				}
				else{
					mp[{{dx, dy}, {xx, yy}}].insert({R[i].y, 0});
					mp[{{dx, dy}, {xx, yy}}].insert({B[j].y, 1});
				}
			}
		}
		for(auto tmp:mp){
			auto se = tmp.second;
			int b = -1;
			int c = 0;
			for(auto tt:se){
				if(tt.second != b){
					b = tt.second;
					c++;
				}
			}
			if(c >= 3){
				print("Yes");
				return;
			}
		}
		print("No");
		return;
	}

	auto dist=[&](Point a, Point b){
		ll dx = a.x - b.x;
		ll dy = a.y - b.y;
		return dx * dx + dy * dy;
	};

	if(lr == 1){
		for(int i = 0; i < lb; i++){
			for(int j = i + 1; j < lb; j++){
				auto x = cross3(B[i], B[j], R[0]);
				if(x == 0 && (dist(B[i], B[j]) >= dist(B[i], R[0])) && (dist(B[i], B[j]) >= dist(B[j], R[0]))){
					print("Yes");
					return;
				}
			}
		}
	}
	if(n == 3){
		print("No");
		return;
	}
	auto BB = B;
	B = convexHull(B, false);
	lb = B.size();

	for(int i = 0; i < lr; i++){
		bool in_ = true;
		bool same = (cross3(B[lb - 1], B[0], R[i]) >= 0);
		for(int j = 0; j < lb - 1; j++){
			bool flg = (cross3(B[j], B[j + 1], R[i]) >= 0);
			if(flg != same){
				in_ = false;
				break;
			}
		}
		if(in_){
			print("Yes");
			return;
		}
	}
	if(lr == 1){
		print("No");
		return;
	}

	ll xx = B[0].x;
	ll yy = B[0].y;
	for(int i = 0; i < lr; i++){
		R[i].x -= xx;
		R[i].y -= yy;
	}
	for(int i = 0; i < lb; i++){
		B[i].x -= xx;
		B[i].y -= yy;
	}

	for(int i = 0; i < BB.size(); i++){
		BB[i].x -= xx;
		BB[i].y -= yy;
	}
	sort(R.begin(), R.end());
	int r = 0;
	long double pi = acos(-1);
	long double pi2 = 2 * pi;

	auto cross=[&](Point &a, Point &b, Point &c, Point &d){
		bool flg1 = __int128_t(cross3(a, b, c)) * __int128_t(cross3(a, b, d)) <= 0;
		bool flg2 = __int128_t(cross3(c, d, a)) * __int128_t(cross3(c, d, b)) <= 0;
		return bool(flg1 && flg2);
	};

	for(int l = 0; l < lr; l++){
		while(1){
			long double d = atan2(R[r].y, R[r].x) - atan2(R[l].y, R[l].x);
			if(d <= 0) d += pi2;
			if(d < pi){
				r++;
				if(r == lr) r = 0;
			}
			else{
				break;
			}
		}
		for(int rr = r - 10; rr <= r + 10; rr++){
			int br = (rr % lr + lr) % lr;
			if(cross(R[l], R[br], B[0], B[lb - 1])){
				print("Yes");
				return;
			}
			for(int j = 0; j < lb - 1; j++){
				if(cross(R[l], R[br], B[j], B[j + 1])){
					print("Yes");
					return;
				}
			}	
		}
	}

	swap(B, BB);
	swap(B, R);
	lr = R.size();
	B = convexHull(B, false);
	lb = B.size();

	for(int i = 0; i < lr; i++){
		bool in_ = true;
		bool same = (cross3(B[lb - 1], B[0], R[i]) >= 0);
		for(int j = 0; j < lb - 1; j++){
			bool flg = (cross3(B[j], B[j + 1], R[i]) >= 0);
			if(flg != same){
				in_ = false;
				break;
			}
		}
		if(in_){
			print("Yes");
			return;
		}
	}


	xx = B[0].x;
	yy = B[0].y;
	for(int i = 0; i < lr; i++){
		R[i].x -= xx;
		R[i].y -= yy;
	}
	for(int i = 0; i < lb; i++){
		B[i].x -= xx;
		B[i].y -= yy;
	}

	sort(R.begin(), R.end());
	r = 0;

	for(int l = 0; l < lr; l++){
		while(1){
			long double d = atan2(R[r].y, R[r].x) - atan2(R[l].y, R[l].x);
			if(d <= 0) d += pi2;
			if(d < pi){
				r++;
				if(r == lr) r = 0;
			}
			else{
				break;
			}
		}
		for(int rr = r - 10; rr <= r + 10; rr++){
			int br = (rr % lr + lr) % lr;
			if(cross(R[l], R[br], B[0], B[lb - 1])){
				print("Yes");
				return;
			}
			for(int j = 0; j < lb - 1; j++){
				if(cross(R[l], R[br], B[j], B[j + 1])){
					print("Yes");
					return;
				}
			}	
		}
	}

	print("No");
}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    int t;
    t = 1;
    // cin >> t;
    while(t--) solve();
	return 0;
}
0