Submission #54988

#TimeUsernameProblemLanguageResultExecution timeMemory
54988linkretPrinted Circuit Board (CEOI12_circuit)C++14
10 / 100
313 ms33792 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second

const int maxn = 1 << 17, inf = 1e9;

struct line {
	int a, b;
};

int n, k;
pair<pii, int> p[maxn];
pii org[maxn];
int arr[maxn];

int addlen[maxn], remlen[maxn];

line *add[maxn];
line *rem[maxn];

pair<pii, int> query[maxn];

vector<int> ans;

pii zero;

ll ccw(const pii &a, const pii &b, const pii &c) {
	return ll(a.f) * (b.s - c.s) + ll(b.f) * (c.s - a.s) + ll(c.f) * (a.s - b.s);
}

bool comp(pair<pii, int> a, pair<pii, int> b) {
	ll c = ccw(zero, a.f, b.f);

	if(c == 0)
		return a.s < b.s;
	return c > 0;
}

bool operator<(line x, line y) {
	const pii &xa = org[x.a];
	const pii &xb = org[x.b];

	const pii &ya = org[y.a];
	const pii &yb = org[y.b];

	if(xa == ya && xb == yb)
		return false;

	ll sum = ccw(xa, ya, xb) + ccw(xb, ya, yb);

	if(!sum) {
		if(xa.s == ya.s)
			return xa.f < ya.f;
		return xa.f < ya.f;
	}

	return sum > 0;
}

void sweep() {
	multiset<line> st;

	for(int t = 1; t <= k; t++) {
		for(int i = 0; i < addlen[t]; i++) {
			st.insert(add[t][i]);
		}
		
		if(!st.empty()) {
			line f = *st.begin();

			auto mnm = query[t];
			
			if(ccw(org[f.a], org[f.b], mnm.f) == 0) {
				ans.push_back(mnm.s);
			}
		}

		for(int i = 0; i < remlen[t]; i++) {
			auto it = st.find(rem[t][i]);
			st.erase(it);
		}
	}
}

void add_edge(int i, int j, int x, int y, bool b) {
	// if(i < j) {
	// 	swap(i, j);
	// 	swap(x, y);
	// }


	if(i < j) {
		if(b) {
			addlen[i]++;
			remlen[j]++;
		} else {
			add[i][addlen[i]++] = line{x, y};
			rem[j][remlen[j]++] = line{x, y};
		}
	} else {
		if(b) {
			addlen[j]++;
			remlen[i]++;
		} else {
			add[j][addlen[j]++] = line{y, x};
			rem[i][addlen[i]++] = line{y, x};
		}
	}
}

void compress() {
	sort(p, p + n, comp);

	for(int i = 0; i <= n; i++) {
		query[i] = {{inf, inf}, inf};
	}

	for(int i = 0; i < n; i++) {
		if(i == 0 || ccw(pii(0, 0), p[i].f, p[i - 1].f))
			k++;
		arr[p[i].s] = k;
		query[k] = min(query[k], p[i]);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	cin >> n;

	for(int i = 0; i < n; i++) {
		pii tmp;
		cin >> tmp.f >> tmp.s;
		
		p[i].f = tmp;
		p[i].s = i;

		org[i] = p[i].f;
	}

	compress();

	for(int i = 0; i < n - 1; i++) 
		add_edge(arr[i], arr[i + 1], i, i + 1, true);
	add_edge(arr[n - 1], arr[0], n - 1, 0, true);

	for(int i = 1; i <= k; i++) {
		add[i] = new line[addlen[i]];
		rem[i] = new line[remlen[i]];
		
		addlen[i] = 0;
		remlen[i] = 0;
	}

	for(int i = 0; i < n - 1; i++) 
		add_edge(arr[i], arr[i + 1], i, i + 1, false);
	add_edge(arr[n - 1], arr[0], n - 1, 0, false);

	sweep();

	cout << ans.size() << endl;

	sort(ans.begin(), ans.end());

	for(int i : ans) {
		cout << i + 1 << " ";
	}

	cout << endl;

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...