Submission #92494

# Submission time Handle Problem Language Result Execution time Memory
92494 2019-01-03T06:15:32 Z qkxwsm Min-max tree (BOI18_minmaxtree) C++14
100 / 100
565 ms 52460 KB
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

random_device(rd);
mt19937 rng(rd());
const long long FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();

struct custom_hash
{
	template<class T>
	unsigned long long operator()(T v) const
	{
		unsigned long long x = v;
		x += FIXED_RANDOM;
		// x += 11400714819323198485ull;
		// x = (x ^ (x >> 30)) * 13787848793156543929ull;
		x = (x ^ (x >> 27)) * 10723151780598845931ull;
		return x ^ (x >> 31);
	}
};

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> using hash_table = gp_hash_table<T, U, custom_hash>;

template<class T>
T randomize(T mod)
{
	return (uniform_int_distribution<T>(0, mod - 1))(rng);
}
template<class T>
void readi(T &x)
{
	x = 0;
	bool negative = false;
	char c = ' ';
	while (c < '-')
	{
		c = getchar();
	}
	if (c == '-')
	{
		negative = true;
		c = getchar();
	}
	while (c >= '0')
	{
		x = x * 10 + (c - '0');
		c = getchar();
	}
	if (negative)
	{
		x = -x;
	}
}
template<class T>
void printi(T output)
{
	if (output == 0)
	{
		putchar('0');
		return;
	}
	if (output < 0)
	{
		putchar('-');
		output = -output;
	}
	int buf[20], n = 0;
	while(output)
	{
		buf[n] = ((output % 10));
		output /= 10;
		n++;
	}
	for (n--; n >= 0; n--)
	{
		putchar(buf[n] + '0');
	}
	return;
}
template<class T>
void ckmin(T &a, T b)
{
	a = min(a, b);
}
template<class T>
void ckmax(T &a, T b)
{
	a = max(a, b);
}
long long expo(long long a, long long e, long long mod)
{
	return ((e == 0) ? 1 : ((expo(a * a % mod, e >> 1, mod)) * ((e & 1) ? a : 1) % mod));
}
template<class T, class U>
void nmod(T &x, U mod)
{
	if (x >= mod) x -= mod;
}
template<class T>
T gcd(T a, T b)
{
	return (b ? gcd(b, a % b) : a);
}

#define y0 ___y0
#define y1 ___y1
#define MP make_pair
#define PB push_back
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second
#define DBG(x) cerr << #x << " = " << (x) << endl
#define SZ(x) ((int) ((x).size()))
#define FOR(i, a, b) for (auto i = (a), i##__end__ = (b); i < i##__end__; i++)
#define FORD(i, a, b) for (auto i = (a) - 1, i##__end__ = (b); i >= i##__end__; i--)
#define ALL(x) (x).begin(), (x).end()

const long double PI = 4.0 * atan(1.0);
const long double EPS = 1e-9;

#define MAGIC 347
#define SINF 10007
#define CO 1000007
#define INF 1000000007
#define BIG 1000000931
#define LARGE 1696969696967ll
#define GIANT 2564008813937411ll
#define LLINF 2696969696969696969ll
#define MAXN 400013

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

int N, Q, T, M;
vi edge[MAXN];
pii bound[MAXN];
int parent[MAXN];
int ancestor[25][MAXN];
pii dup[25][MAXN];
int st[MAXN], ft[MAXN], depth[MAXN];
int ans[MAXN];
bitset<MAXN> vis, VIS;

bool insubt(int u, int v)
{
	return (u == N) || (st[u] <= st[v] && st[v] <= ft[u]);
}
void dfs(int u)
{
	st[u] = ft[u] = T;
	T++;
	for (int v : edge[u])
	{
		if (v == parent[u]) continue;
		parent[v] = u;
		depth[v] = depth[u] + 1;
		dfs(v);
		ft[u] = ft[v];
	}
}
int lca(int u, int v)
{
	//how far up does v go before u
	if (insubt(v, u)) return -1;
	FORD(i, 20, 0)
	{
		if (!insubt(ancestor[i][v], u))
		{
			v = ancestor[i][v];
		}
	}
	return v;
}


bitset<MAXN> color, seen;
int V;
vector<int> edge1[MAXN];
int match[MAXN];

bool dfs1(int u)
{
	if (seen[u])
	{
		return false;
	}
	seen[u] = true;
	for (int v : edge1[u])
	{
		if (match[v] == -1 || dfs1(match[v]))
		{
			match[u] = v;
			match[v] = u;
			return true;
		}
	}
	return false;
}
int matching()
{
	int res = 0;
	for (int i = 0; i < V; i++)
	{
		match[i] = -1;
	}
	for (int i = 0; i < V; i++)
	{
		if (color[i])
		{
			continue;
		}
		seen.reset();
		if (dfs1(i))
		{
			res++;
		}
	}
	return res;
}
void addedge(int u, int v)
{
	// cerr << "addedge " << u << " -> " << v << endl;
	edge1[u].PB(v);
	edge1[v].PB(u);
}

int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	// cout << fixed << setprecision(10);
	// cerr << fixed << setprecision(10);
	// if (fopen("file.in", "r"))
	// {
	// 	freopen ("file.in", "r", stdin);
	// 	freopen ("file.out", "w", stdout);
	// }
	cin >> N;
	FOR(i, 0, N - 1)
	{
		int u, v; cin >> u >> v; u--; v--;
		edge[u].PB(v);
		edge[v].PB(u);
	}
	parent[0] = N; dfs(0);
	FOR(i, 0, 22)
	{
		ancestor[i][N] = N;
	}
	FOR(i, 0, N)
	{
		ancestor[0][i] = parent[i];
		dup[0][i] = {-INF, INF};
	}
	FOR(i, 1, 21)
	{
		FOR(j, 0, N)
		{
			ancestor[i][j] = ancestor[i - 1][ancestor[i - 1][j]];
			dup[i][j] = {-INF, INF};
		}
	}
	cin >> Q;
	while(Q--)
	{
		int u, v, val;
		char typ;
		cin >> typ >> u >> v >> val; u--; v--;
		if (typ == 'm')
		{
			int w = lca(u, v), diff = depth[v] - depth[w] + 1;
			if (w != -1)
			{
				int x = v;
				FORD(i, 20, 0)
				{
					if (diff & (1 << i))
					{
						ckmax(dup[i][x].fi, val);
						x = ancestor[i][x];
					}
				}
			}
			w = lca(v, u);
			if (w != -1)
			{
				int x = u, diff = depth[u] - depth[w] + 1;
				FORD(i, 20, 0)
				{
					if (diff & (1 << i))
					{
						ckmax(dup[i][x].fi, val);
						x = ancestor[i][x];
					}
				}
			}
		}
		if (typ == 'M')
		{
			int w = lca(u, v);
			if (w != -1)
			{
				int x = v, diff = depth[v] - depth[w] + 1;
				FORD(i, 20, 0)
				{
					if (diff & (1 << i))
					{
						ckmin(dup[i][x].se, val);
						x = ancestor[i][x];
					}
				}
			}
			w = lca(v, u);
			if (w != -1)
			{
				int x = u, diff = depth[u] - depth[w] + 1;
				FORD(i, 20, 0)
				{
					if (diff & (1 << i))
					{
						ckmin(dup[i][x].se, val);
						x = ancestor[i][x];
					}
				}
			}
		}
	}
	FORD(i, 20, 1)
	{
		FOR(j, 0, N)
		{
			ckmin(dup[i - 1][j].se, dup[i][j].se);
			ckmin(dup[i - 1][ancestor[i - 1][j]].se, dup[i][j].se);
			ckmax(dup[i - 1][j].fi, dup[i][j].fi);
			ckmax(dup[i - 1][ancestor[i - 1][j]].fi, dup[i][j].fi);
		}
	}
	FOR(i, 0, N)
	{
		bound[i] = dup[0][i];
		// cerr << bound[i].fi << ' ' << bound[i].se << endl;
	}
	vi compress;
	//you can have one or the other, but not both!
	FOR(i, 1, N)
	{
		compress.PB(bound[i].fi);
		compress.PB(bound[i].se);
	}
	compress.PB(-INF); compress.PB(INF);
	sort(ALL(compress));
	compress.erase(unique(ALL(compress)), compress.end());
	V = SZ(compress);
	// DBG(V);
	FOR(i, 1, N)
	{
		bound[i].fi = LB(ALL(compress), bound[i].fi) - compress.begin();
		bound[i].se = LB(ALL(compress), bound[i].se) - compress.begin();
		// cerr << bound[i].fi << ' ' << bound[i].se << endl;
	}
	FOR(i, 0, V) color[i] = 1;
	//you add an edge from x
	FOR(i, 1, N)
	{
		if (bound[i].fi != 0)
		{
			addedge(bound[i].fi, i + V - 1);
		}
		if (bound[i].se != V - 1)
		{
			addedge(bound[i].se, i + V - 1);
		}
	}
	V += (N - 1);
	int x = matching();
	V -= (N - 1);
	FOR(i, 1, V - 1)
	{
		ans[match[i] - (V - 1)] = i;
	}
	bitset<MAXN> VIS; VIS.reset();
	FOR(i, 1, N)
	{
		if (ans[i] == 0) ans[i] = bound[i].fi;
		VIS[ans[i]] = true;
	}
	FOR(i, 1, V - 1)
	{
		if (!VIS[i])
		{
			cout << "stupid\n";
			return 0;
		}
	}
	FOR(i, 1, N)
	{
		cout << i + 1 << ' ' << parent[i] + 1 << ' ' << compress[ans[i]] << '\n';
	}
	// cerr << "time elapsed = " << (clock() / (CLOCKS_PER_SEC / 1000)) << " ms" << endl;
	return 0;
}
/* READ READ READ
* int overflow, maxn too small, special cases (n=1?, two distinct?), cin.tie() interactive
* reread the problem, try small cases
* note down possible sources of error as you go
* do smth instead of nothing
*/

Compilation message

minmaxtree.cpp: In function 'int32_t main()':
minmaxtree.cpp:393:6: warning: unused variable 'x' [-Wunused-variable]
  int x = matching();
      ^
minmaxtree.cpp:289:48: warning: array subscript is below array bounds [-Warray-bounds]
    int w = lca(u, v), diff = depth[v] - depth[w] + 1;
                                         ~~~~~~~^
# Verdict Execution time Memory Grader output
1 Correct 21 ms 19576 KB Output is correct
2 Correct 20 ms 19576 KB Output is correct
3 Correct 20 ms 19616 KB Output is correct
4 Correct 20 ms 19704 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 449 ms 49132 KB Output is correct
2 Correct 329 ms 47308 KB Output is correct
3 Correct 423 ms 47996 KB Output is correct
4 Correct 517 ms 49516 KB Output is correct
5 Correct 514 ms 47980 KB Output is correct
6 Correct 397 ms 48108 KB Output is correct
7 Correct 344 ms 47460 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 305 ms 45408 KB Output is correct
2 Correct 286 ms 45676 KB Output is correct
3 Correct 334 ms 46488 KB Output is correct
4 Correct 340 ms 47084 KB Output is correct
5 Correct 342 ms 45936 KB Output is correct
6 Correct 344 ms 46456 KB Output is correct
7 Correct 314 ms 46192 KB Output is correct
8 Correct 343 ms 46060 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 21 ms 19576 KB Output is correct
2 Correct 20 ms 19576 KB Output is correct
3 Correct 20 ms 19616 KB Output is correct
4 Correct 20 ms 19704 KB Output is correct
5 Correct 449 ms 49132 KB Output is correct
6 Correct 329 ms 47308 KB Output is correct
7 Correct 423 ms 47996 KB Output is correct
8 Correct 517 ms 49516 KB Output is correct
9 Correct 514 ms 47980 KB Output is correct
10 Correct 397 ms 48108 KB Output is correct
11 Correct 344 ms 47460 KB Output is correct
12 Correct 305 ms 45408 KB Output is correct
13 Correct 286 ms 45676 KB Output is correct
14 Correct 334 ms 46488 KB Output is correct
15 Correct 340 ms 47084 KB Output is correct
16 Correct 342 ms 45936 KB Output is correct
17 Correct 344 ms 46456 KB Output is correct
18 Correct 314 ms 46192 KB Output is correct
19 Correct 343 ms 46060 KB Output is correct
20 Correct 377 ms 47572 KB Output is correct
21 Correct 342 ms 48956 KB Output is correct
22 Correct 329 ms 49012 KB Output is correct
23 Correct 353 ms 49364 KB Output is correct
24 Correct 499 ms 51628 KB Output is correct
25 Correct 493 ms 52460 KB Output is correct
26 Correct 478 ms 51940 KB Output is correct
27 Correct 479 ms 51304 KB Output is correct
28 Correct 460 ms 50640 KB Output is correct
29 Correct 565 ms 50620 KB Output is correct
30 Correct 426 ms 49540 KB Output is correct
31 Correct 470 ms 49744 KB Output is correct
32 Correct 380 ms 50388 KB Output is correct
33 Correct 385 ms 49904 KB Output is correct
34 Correct 374 ms 49904 KB Output is correct
35 Correct 380 ms 49560 KB Output is correct