Submission #736218

# Submission time Handle Problem Language Result Execution time Memory
736218 2023-05-05T10:29:31 Z marvinthang Regions (IOI09_regions) C++17
100 / 100
2216 ms 40956 KB
/*************************************
*    author: marvinthang             *
*    created: 05.05.2023 16:50:15    *
*************************************/

#include <bits/stdc++.h>

using namespace std;

#define                  fi  first
#define                  se  second
#define                left  ___left
#define               right  ___right
#define                TIME  (1.0 * clock() / CLOCKS_PER_SEC)
#define             MASK(i)  (1LL << (i))
#define           BIT(x, i)  ((x) >> (i) & 1)
#define  __builtin_popcount  __builtin_popcountll
#define              ALL(v)  (v).begin(), (v).end()
#define           REP(i, n)  for (int i = 0, _n = (n); i < _n; ++i)
#define          REPD(i, n)  for (int i = (n); i--; )
#define        FOR(i, a, b)  for (int i = (a), _b = (b); i < _b; ++i) 
#define       FORD(i, b, a)  for (int i = (b), _a = (a); --i >= _a; ) 
#define       FORE(i, a, b)  for (int i = (a), _b = (b); i <= _b; ++i) 
#define      FORDE(i, b, a)  for (int i = (b), _a = (a); i >= _a; --i) 
#define        scan_op(...)  istream & operator >> (istream &in, __VA_ARGS__ &u)
#define       print_op(...)  ostream & operator << (ostream &out, const __VA_ARGS__ &u)
#ifdef LOCAL
    #include "debug.h"
#else
    #define file(name) if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
    #define DB(...) 23
    #define db(...) 23
    #define debug(...) 23
#endif

template <class U, class V> scan_op(pair <U, V>)  { return in >> u.first >> u.second; }
template <class T> scan_op(vector <T>)  { for (size_t i = 0; i < u.size(); ++i) in >> u[i]; return in; }
template <class U, class V> print_op(pair <U, V>)  { return out << '(' << u.first << ", " << u.second << ')'; }
template <size_t i, class T> ostream & print_tuple_utils(ostream &out, const T &tup) { if constexpr(i == tuple_size<T>::value) return out << ")";  else return print_tuple_utils<i + 1, T>(out << (i ? ", " : "(") << get<i>(tup), tup); }
template <class ...U> print_op(tuple<U...>) { return print_tuple_utils<0, tuple<U...>>(out, u); }
template <class Con, class = decltype(begin(declval<Con>()))> typename enable_if <!is_same<Con, string>::value, ostream&>::type operator << (ostream &out, const Con &con) { out << '{'; for (__typeof(con.begin()) it = con.begin(); it != con.end(); ++it) out << (it == con.begin() ? "" : ", ") << *it; return out << '}'; }

// end of template

const int MAX = 2e5 + 5;
const int MAX_R = 25e3 + 3;
const int BLOCK_SIZE = 500;

int N, R, Q, H[MAX];
vector <int> adj[MAX], List[MAX_R];
vector <pair <int, int>> List_f[MAX_R];
int id[MAX_R], res1[MAX / BLOCK_SIZE + 5][MAX_R], cnt[MAX_R], res2[MAX / BLOCK_SIZE + 5][MAX_R], numBig;
int tin[MAX], tout[MAX], treeSize[MAX];

void init(void) {
	cin >> N >> R >> Q;
	FORE(i, 1, N) {
		if (i > 1) {
			int p; cin >> p;
			adj[p].push_back(i);
		}
		cin >> H[i];
		++cnt[H[i]];
	}
}

void update(int u, int add) {
	if (~id[H[u]]) cnt[id[H[u]]] += add;
	for (int v: adj[u]) update(v, add);
}

void dfs(int u) {
	static int timeDfs = 0;
	tin[u] = ++timeDfs;
	if (~id[H[u]]) ++cnt[id[H[u]]];
	List_f[H[u]].emplace_back(tin[u] - 1, -1);
	List[H[u]].push_back(tin[u]);
	REP(i, numBig) res1[i][H[u]] += cnt[i];
	treeSize[u] = 1;
	for (int v: adj[u]) {
		dfs(v);
		treeSize[u] += treeSize[v];
	}
	if (~id[H[u]]) --cnt[id[H[u]]];
	tout[u] = timeDfs;
	List_f[H[u]].emplace_back(tout[u], 1);
}

void dfs2(int u) {
	int heavy = -1;
	for (int v: adj[u]) if (heavy == -1 || treeSize[heavy] < treeSize[v]) heavy = v;
	for (int v: adj[u]) if (v != heavy) {
		dfs2(v);
		update(v, -1);
	}
	if (heavy != -1) dfs2(heavy);
	for (int v: adj[u]) if (v != heavy) update(v, 1);
	if (~id[H[u]]) ++cnt[id[H[u]]];
	REP(i, numBig) res2[i][H[u]] += cnt[i];
}

void process(void) {
	memset(id, -1, sizeof(id));
	FORE(i, 1, R) {
		if (cnt[i] > BLOCK_SIZE) id[i] = numBig++;
		cnt[i] = 0;
	}
	dfs(1);
	dfs2(1);
	while (Q--) {
		int a, b; cin >> a >> b;
		if (~id[a]) cout << res1[id[a]][b] << endl;
		else if (~id[b]) cout << res2[id[b]][a] << endl;
		else {
			int res = 0, i = 0;
			for (auto [u, f]: List_f[a]) {
				while (i < (int) List[b].size() && List[b][i] <= u) ++i;
				res += f * i;
			}
			cout << res << endl;
		}
	}
}

int main(void) {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); // cout.tie(nullptr);
	file("regions");
	init();
	process();
	// cerr << "Time elapsed: " << TIME << " s.\n";
	return (0^0);
}

Compilation message

regions.cpp: In function 'int main()':
regions.cpp:30:61: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   30 |     #define file(name) if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
      |                                                      ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
regions.cpp:127:2: note: in expansion of macro 'file'
  127 |  file("regions");
      |  ^~~~
regions.cpp:30:94: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   30 |     #define file(name) if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
      |                                                                                       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
regions.cpp:127:2: note: in expansion of macro 'file'
  127 |  file("regions");
      |  ^~~~
# Verdict Execution time Memory Grader output
1 Correct 5 ms 6224 KB Output is correct
2 Correct 4 ms 6224 KB Output is correct
3 Correct 6 ms 6224 KB Output is correct
4 Correct 8 ms 6224 KB Output is correct
5 Correct 9 ms 6352 KB Output is correct
6 Correct 12 ms 6456 KB Output is correct
7 Correct 27 ms 6352 KB Output is correct
8 Correct 43 ms 6480 KB Output is correct
9 Correct 48 ms 7204 KB Output is correct
10 Correct 100 ms 7032 KB Output is correct
11 Correct 64 ms 7528 KB Output is correct
12 Correct 152 ms 8360 KB Output is correct
13 Correct 163 ms 8016 KB Output is correct
14 Correct 90 ms 8804 KB Output is correct
15 Correct 203 ms 13296 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 787 ms 13328 KB Output is correct
2 Correct 939 ms 11688 KB Output is correct
3 Correct 1364 ms 16304 KB Output is correct
4 Correct 207 ms 8656 KB Output is correct
5 Correct 290 ms 11564 KB Output is correct
6 Correct 679 ms 10432 KB Output is correct
7 Correct 891 ms 11964 KB Output is correct
8 Correct 902 ms 20240 KB Output is correct
9 Correct 1222 ms 20268 KB Output is correct
10 Correct 1981 ms 27852 KB Output is correct
11 Correct 2216 ms 19868 KB Output is correct
12 Correct 734 ms 21144 KB Output is correct
13 Correct 1383 ms 22024 KB Output is correct
14 Correct 1552 ms 24760 KB Output is correct
15 Correct 1986 ms 28688 KB Output is correct
16 Correct 1819 ms 39488 KB Output is correct
17 Correct 1796 ms 40956 KB Output is correct