답안 #161545

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
161545 2019-11-03T04:27:51 Z qkxwsm Sunčanje (COCI18_suncanje) C++14
0 / 130
2085 ms 59388 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

template<class T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template<class T, class U>
void ckmin(T &a, U b)
{
	if (a > b) a = b;
}
template<class T, class U>
void ckmax(T &a, U b)
{
	if (a < b) a = b;
}

#define y1 what
#define y2 chard
#define MP make_pair
#define PB push_back
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second
#define FOR(i, a, b) for (auto i = (a); i < (b); i++)
#define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--)
#define SZ(x) ((int) ((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define MAXN 140013

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;
typedef pair<pii, pii> ppp;

int N;
ppp arr[MAXN];
vi xs, ys;
bitset<MAXN> ans;
vector<pair<pii, int> > ql[MAXN], qr[MAXN], del[MAXN], ins[MAXN];
int lazy[4 * MAXN];
pii stor[4 * MAXN];
set<pair<pii, int> > fw, bw;

pii comb(pii a, pii b)
{
	if (a.fi < b.fi) return a;
	if (a.fi > b.fi) return b;
	return {a.fi, a.se + b.se};
}
void build(int w, int L, int R)
{
	stor[w] = {0, R - L + 1};
	lazy[w] = 0;
	if (L == R) return;
	int mid = (L + R) >> 1;
	build(w << 1, L, mid);
	build(w << 1 | 1, mid + 1, R);
}
void push(int w, int L, int R)
{
	if (lazy[w] == 0);
	stor[w].fi += lazy[w];
	if (L != R)
	{
		lazy[w << 1] += lazy[w];
		lazy[w << 1 | 1] += lazy[w];
	}
	lazy[w] = 0;
	return;
}
void update(int w, int L, int R, int a, int b, int v)
{
	// cerr << L << ' ' << R << ' ' << a << ' ' << b << ' ' << v << endl;
	push(w, L, R);
	if (b < L || R < a) return;
	if (a <= L && R <= b)
	{
		lazy[w] += v;
		push(w, L, R);
		return;
	}
	int mid = (L + R) >> 1;
	update(w << 1, L, mid, a, b, v);
	update(w << 1 | 1, mid + 1, R, a, b, v);
	stor[w] = comb(stor[w << 1], stor[w << 1 | 1]);
}
pii query(int w, int L, int R, int a, int b)
{
	push(w, L, R);
	if (a <= L && R <= b)
	{
		return stor[w];
	}
	int mid = (L + R) >> 1;
	if (b <= mid) return query(w << 1, L, mid, a, b);
	if (mid < a) return query(w << 1 | 1, mid + 1, R, a, b);
	return comb(query(w << 1, L, mid, a, b), query(w << 1 | 1, mid + 1, R, a, b));
}

void solve(int L, int R)
{
	if (L == R) return;
	int mid = (L + R) >> 1;
	solve(L, mid);
	solve(mid + 1, R);
	// cerr << "SOLVE " << L << ' ' << R << endl;
	xs.clear(); ys.clear();
	FOR(i, L, R + 1)
	{
		xs.PB(arr[i].fi.fi); ys.PB(arr[i].fi.se); xs.PB(arr[i].se.fi); ys.PB(arr[i].se.se);
	}
	// cerr << SZ(xs) << ' ' << SZ(ys) << endl;
	sort(ALL(xs)); xs.erase(unique(ALL(xs)), xs.end());
	sort(ALL(ys)); ys.erase(unique(ALL(ys)), ys.end());
	// cerr << SZ(xs) << ' ' << SZ(ys) << endl;
	FOR(i, 0, SZ(xs))
	{
		ql[i].clear(); qr[i].clear(); ins[i].clear(); del[i].clear();
	}
	FOR(i, L, mid + 1)
	{
		int x1 = LB(ALL(xs), arr[i].fi.fi) - xs.begin();
		int y1 = LB(ALL(ys), arr[i].fi.se) - ys.begin();
		int x2 = LB(ALL(xs), arr[i].se.fi) - xs.begin() - 1;
		int y2 = LB(ALL(ys), arr[i].se.se) - ys.begin() - 1;
		ql[x1].PB({{y1, y2}, i});
		qr[x2].PB({{y1, y2}, i});
		// cerr << x2 << " WITHIN " << SZ(xs) << endl;
		// cerr << "query " << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << endl;
		//these are the guys that query.
	}
	FOR(i, mid + 1, R + 1)
	{
		int x1 = LB(ALL(xs), arr[i].fi.fi) - xs.begin();
		int y1 = LB(ALL(ys), arr[i].fi.se) - ys.begin();
		int x2 = LB(ALL(xs), arr[i].se.fi) - xs.begin() - 1;
		int y2 = LB(ALL(ys), arr[i].se.se) - ys.begin() - 1;
		ins[x1].PB({{y1, y2}, i});
		del[x2].PB({{y1, y2}, i});
		// cerr << "send " << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << endl;
		//these are the guys that send.
	}
	build(1, 0, SZ(ys) - 1);
	FOR(i, 0, SZ(xs))
	{
		// cerr << "YES\n";
		// cerr << SZ(ins[i]) << endl;
		for (auto a : ins[i])
		{
			// cerr << "ALIVE\n";
			// cerr << "KILLER " << a.fi.fi << ' ' << a.fi.se << endl;
			update(1, 0, SZ(ys) - 1, a.fi.fi, a.fi.se, 1);
			int lo = a.fi.fi, hi = a.fi.se;
			auto it = fw.LB({{lo, -1}, -1});
			while(it != fw.end() && it -> fi.fi <= hi)
			{
				// cerr << it -> fi.fi << endl;
				ans[it -> se] = true;
				bw.erase({{it -> fi.se, it -> fi.fi}, it -> se});
				it = fw.erase(it);
			}
			auto jt = bw.LB({{hi + 1, -1}, -1});
			while(jt != bw.begin() && (prev(jt) -> fi.fi >= lo))
			{
				jt = prev(jt);
				ans[jt -> se] = true;
				bw.erase({{jt -> fi.se, jt -> fi.fi}, jt -> se});
				jt = bw.erase(jt);
			}
		}
		for (auto a : ql[i])
		{
			int idx = a.se;
			pii p = query(1, 0, SZ(ys) - 1, a.fi.fi, a.fi.se);
			if (p.fi != 0 || p.se != (a.fi.se - a.fi.fi + 1))
			{
				ans[idx] = true;
			}
			fw.insert({a.fi, idx});
			bw.insert({{a.fi.se, a.fi.fi}, idx});
		}
		for (auto a : qr[i])
		{
			int idx = a.se;
			pii p = query(1, 0, SZ(ys) - 1, a.fi.fi, a.fi.se);
			if (p.fi != 0 || p.se != (a.fi.se - a.fi.fi + 1))
			{
				ans[idx] = true;
			}
			if (fw.find(a) != fw.end())
			{
				fw.erase({a.fi, idx});
				bw.erase({{a.fi.se, a.fi.fi}, idx});
			}
		}
		for (auto a : del[i])
		{
			update(1, 0, SZ(ys) - 1, a.fi.fi, a.fi.se, -1);
		}
	}
	//either it overlaps on the left, or it overlaps on the right, or it is completely contained
	//use the print segtree to solve the noraml case.
	//otherwise the killer has to be inside the query.
	//then we have a bunc hof query rectangles, and then
	//so when you have a killer rectangle become alive, you just use the set.
}

int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(4);
	cin >> N;
	FOR(i, 0, N)
	{
		cin >> arr[i].fi.fi >> arr[i].fi.se >> arr[i].se.fi >> arr[i].se.se;
		arr[i].se.fi += (arr[i].fi.fi);
		arr[i].se.se += (arr[i].fi.se);
	}
	//update this rectangle.
	//ehh seems hard.
	//update r5 with 5. then update r4 with 4. then update r3 with 3.
	//then if any point in rect x is updated with > x then you lose.
	//OR
	//in decreasing order of rectangles, update every point in a rectangle by 1.
	//then for a given rectangle, query if there's anything on in it.
	//bleh, you can like, store ranges of ok guys.
	//the ndoe in the segtree stores, THERE'S AT LEAST ONE GUY IN HERE WITH THIS.
	//then when you update x you don't even need to worry about its children.
	solve(0, N - 1);
	FOR(i, 0, N)
	{
		cout << (ans[i] ? "NE" : "DA") << '\n';
	}
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 79 ms 14964 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 211 ms 16620 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 423 ms 19436 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 621 ms 21148 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 985 ms 26068 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1059 ms 26344 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 976 ms 26236 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1336 ms 53360 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1631 ms 54644 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 2085 ms 59388 KB Execution killed with signal 11 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -