답안 #942085

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
942085 2024-03-10T08:35:09 Z qin Amusement Park (JOI17_amusement_park) C++17
83 / 100
25 ms 10488 KB
#include <bits/stdc++.h>
#include "Joi.h"
#define fi first
#define se second
#define ssize(x) int(x.size())
#define pn printf("\n")
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend();
#define vv vector
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
int inf = 2e09; ll infll = 2e18; int mod = 119<<23|1, S = 60;
#ifdef LOCAL
int Move(int x){ return x; }
void MessageBoard(int a, int b){}
#endif
struct graph{
		vv<vv<int>> bg, g;
		vv<int> vis, good, is_top, sz, depth;
		vv<ll> info;
		void init(int n){
				bg.resize(n+1), g.resize(n+1), vis.resize(n+1), good.resize(n+1, 0), info.resize(n+1, 0), sz.resize(n+1), is_top.resize(n+1), depth.resize(n+1);
		}
		void add_edge_b(int a, int b){ bg[a].emplace_back(b), bg[b].emplace_back(a); }
		void add_edge(int a, int b){ g[a].emplace_back(b), g[b].emplace_back(a); }
		void get_tree(int x){
				vis[x] = 1;
				for(int &u : bg[x]) if(!vis[u]) add_edge(x, u), get_tree(u);
		}
		vv<int> find_closest_group(int x){ // zwroci wektor tych, po ktorych musze sie poruszac, by dojsc do najblizszej grupy
				fill(all(vis), 0);
				int v;
				vv<int> ret;
				queue<int> q; q.emplace(x); vis[x] = -1;
				while(!q.empty()){
						v = q.front(); q.pop();
						if(good[v]){
								while(vis[v] != -1) ret.emplace_back(v), v = vis[v];
								break;
						}
						for(int &u : g[v]) if(!vis[u]) vis[u] = v, q.emplace(u);
				}
				q = queue<int>();
				return ret;
		}
		int bit = 0;
		ll process(int x, int gr, ll X, int par){ // X -1 = zwroc, w przeciwnym wypadku zakoduj TRZEBA PAMIETAC, BY POSORTOWAC WEKTOR SASIEDZTWA
				if(is_top[x]) bit = 0;
				ll ret = 0;
				//~ printf("%d: %lld %d\n", x, info[x], bit);
				if(X == -1) ret = info[x]<<bit;
				else info[x] = ((X&(1ll<<bit)) == 0) ? 0 : 1, depth[x] = 1;
				for(int &u : g[x]) if(good[u] == gr && u != par) ++bit, ret += process(u, gr, X, x), depth[x] = max(depth[x], depth[u]+1);
				return ret;
		}
		int l = 0; // ktora grupa
		void get_groups(int x, int par, ll X){
				//~ printf("%d\n", x);
				sz[x] = 1;
				for(int &u : g[x]) if(u != par) get_groups(u, x, X), sz[x] += sz[u];
				if(sz[x] >= 60){
						int cnt = 0, v, p;
						good[x] = ++l, is_top[x] = 1;
						queue<pii> q; q.emplace(x, par);
						while(!q.empty() && cnt < 60){
								v = q.front().fi, p = q.front().se; q.pop(), ++cnt, good[v] = l;
								for(int &u : g[v]) if(u != p && !good[u]) q.emplace(u, v);
						}
						if(X != -1) process(x, good[x], X, 0);
						q = queue<pii>(), sz[x] = 0;
				}
		}
} g;
bool comp(int a, int b){ return g.depth[a] < g.depth[b]; }
void Joi(int n, int m, int a[], int b[], ll X, int T){
		g.init(n+1);
		for(int i = 0; i < m; ++i) g.add_edge_b(a[i]+1, b[i]+1);
		g.get_tree(31);
		for(int i = 1; i <= n; ++i) sort(all(g.g[i]), comp);
		g.get_groups(31, 0, X);
		for(int i = 1; i <= n; ++i) MessageBoard(i-1, g.info[i]);
}
#ifdef LOCAL
void answer(){
	
}
int main(){
		int T = 1;
		for(++T; --T; ) answer();
		return 0;
}
#endif
#include <bits/stdc++.h>
#include "Ioi.h"
#define fi first
#define se second
#define ssize(x) int(x.size())
#define pn printf("\n")
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend();
#define vv vector
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#ifdef LOCAL
int Move(int x){ return x; }
void MessageBoard(int a, int b){}
#endif
struct gph{
		vv<vv<int>> bg, g;
		vv<int> vis, good, is_top, sz, depth;
		vv<ll> info;
		void init(int n){
				bg.resize(n+1), g.resize(n+1), vis.resize(n+1), good.resize(n+1, 0), info.resize(n+1, 0), sz.resize(n+1), is_top.resize(n+1), depth.resize(n+1);
		}
		void add_edge_b(int a, int b){ bg[a].emplace_back(b), bg[b].emplace_back(a); }
		void add_edge(int a, int b){ g[a].emplace_back(b), g[b].emplace_back(a); }
		void get_tree(int x){
				vis[x] = 1;
				for(int &u : bg[x]) if(!vis[u]) add_edge(x, u), get_tree(u);
		}
		vv<int> find_closest_group(int x){ // zwroci wektor tych, po ktorych musze sie poruszac, by dojsc do najblizszej grupy
				fill(all(vis), 0);
				int v;
				vv<int> ret;
				queue<int> q; q.emplace(x); vis[x] = -1;
				while(!q.empty()){
						v = q.front(); q.pop();
						if(good[v]){
								while(vis[v] != -1) ret.emplace_back(v), v = vis[v];
								break;
						}
						for(int &u : g[v]) if(!vis[u]) vis[u] = v, q.emplace(u);
				}
				q = queue<int>();
				return ret;
		}
		int bit = 0;
		int get_info(int x, int gr, int par, int val){
				int ret = is_top[x] ? x : 0;
				info[x] = val, ++bit;
				for(int &u : g[x]) if(u != par && good[u] == gr) ret = max(ret, get_info(u, gr, x, Move(u-1)));
				if(par && bit < 60) Move(par-1);
				return ret;
		}
		ll process(int x, int gr, ll X, int par){ // X -1 = zwroc, w przeciwnym wypadku zakoduj TRZEBA PAMIETAC, BY POSORTOWAC WEKTOR SASIEDZTWA
				if(is_top[x]) bit = 0;
				ll ret = 0;
				//~ printf("%d: %lld %d\n", x, info[x], bit);
				if(X == -1) ret = info[x]<<bit;
				else info[x] = ((X&(1ll<<bit)) == 0) ? 0 : 1, depth[x] = 1;
				for(int &u : g[x]) if(good[u] == gr && u != par) ++bit, ret += process(u, gr, X, x), depth[x] = max(depth[x], depth[u]+1);
				return ret;
		}
		int l = 0; // ktora grupa
		void get_groups(int x, int par, ll X){
				//~ printf("%d\n", x);
				sz[x] = 1;
				for(int &u : g[x]) if(u != par) get_groups(u, x, X), sz[x] += sz[u];
				if(sz[x] >= 60){
						int cnt = 0, v, p;
						good[x] = ++l, is_top[x] = 1;
						queue<pii> q; q.emplace(x, par);
						while(!q.empty() && cnt < 60){
								v = q.front().fi, p = q.front().se; q.pop(), ++cnt, good[v] = l;
								for(int &u : g[v]) if(u != p && !good[u]) q.emplace(u, v);
						}
						if(X != -1) process(x, good[x], X, 0);
						q = queue<pii>(), sz[x] = 0;
				}
		}
} g;
bool comp(int a, int b){ return g.depth[a] < g.depth[b]; }
ll Ioi(int n, int m, int a[], int b[], int p, int val, int T){
		g.init(n+1); ++p;
		for(int i = 0; i < m; ++i) g.add_edge_b(a[i]+1, b[i]+1);
		g.get_tree(31);
		for(int i = 1; i <= n; ++i) sort(all(g.g[i]), comp);
		g.get_groups(31, 0, -1);
		vv<int> path = g.find_closest_group(p);
		while(!path.empty()) p = path.back(), path.pop_back(), val = Move(p-1);
		g.bit = 0; int TOP = g.get_info(p, g.good[p], 0, val);
		ll ret = g.process(TOP, g.good[TOP], -1, 0);
		//~ printf("%lld\n", ret);
		return ret;
		return 0;
}
#ifdef LOCAL
void answer(){
	
}
int main(){
		int T = 1;
		for(++T; --T; ) answer();
		return 0;
}
#endif
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 796 KB Output is correct
2 Correct 0 ms 784 KB Output is correct
3 Correct 1 ms 800 KB Output is correct
4 Correct 0 ms 780 KB Output is correct
5 Correct 1 ms 784 KB Output is correct
6 Correct 0 ms 796 KB Output is correct
7 Correct 1 ms 800 KB Output is correct
8 Correct 1 ms 800 KB Output is correct
9 Correct 1 ms 792 KB Output is correct
10 Correct 1 ms 780 KB Output is correct
11 Correct 3 ms 1608 KB Output is correct
12 Correct 0 ms 796 KB Output is correct
13 Correct 1 ms 800 KB Output is correct
14 Correct 2 ms 788 KB Output is correct
15 Correct 1 ms 800 KB Output is correct
16 Correct 2 ms 800 KB Output is correct
17 Correct 1 ms 792 KB Output is correct
18 Correct 2 ms 792 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 8548 KB Output is correct
2 Correct 25 ms 8500 KB Output is correct
3 Correct 23 ms 8556 KB Output is correct
4 Correct 13 ms 4328 KB Output is correct
5 Correct 15 ms 7916 KB Output is correct
6 Correct 13 ms 5860 KB Output is correct
7 Correct 17 ms 7136 KB Output is correct
8 Correct 16 ms 6636 KB Output is correct
9 Correct 14 ms 6896 KB Output is correct
10 Correct 12 ms 4592 KB Output is correct
11 Correct 12 ms 4580 KB Output is correct
12 Correct 11 ms 4052 KB Output is correct
13 Correct 13 ms 4060 KB Output is correct
14 Correct 11 ms 4328 KB Output is correct
15 Correct 13 ms 4328 KB Output is correct
16 Correct 12 ms 4332 KB Output is correct
17 Correct 12 ms 4328 KB Output is correct
18 Correct 16 ms 4324 KB Output is correct
19 Correct 13 ms 4328 KB Output is correct
20 Correct 12 ms 7400 KB Output is correct
21 Correct 12 ms 7392 KB Output is correct
22 Correct 14 ms 7400 KB Output is correct
23 Correct 16 ms 5860 KB Output is correct
24 Correct 16 ms 7144 KB Output is correct
25 Correct 14 ms 6100 KB Output is correct
26 Correct 15 ms 6368 KB Output is correct
27 Correct 14 ms 6412 KB Output is correct
28 Correct 14 ms 6884 KB Output is correct
29 Correct 14 ms 6404 KB Output is correct
30 Correct 13 ms 6368 KB Output is correct
31 Correct 1 ms 796 KB Output is correct
32 Correct 1 ms 784 KB Output is correct
33 Correct 1 ms 800 KB Output is correct
34 Correct 1 ms 800 KB Output is correct
35 Correct 1 ms 792 KB Output is correct
36 Correct 0 ms 788 KB Output is correct
37 Correct 1 ms 784 KB Output is correct
38 Correct 1 ms 780 KB Output is correct
39 Correct 0 ms 796 KB Output is correct
40 Correct 1 ms 784 KB Output is correct
41 Correct 1 ms 796 KB Output is correct
42 Correct 0 ms 784 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 796 KB Output is correct
2 Correct 0 ms 784 KB Output is correct
3 Correct 0 ms 796 KB Output is correct
4 Correct 3 ms 2464 KB Output is correct
5 Correct 3 ms 2364 KB Output is correct
6 Correct 2 ms 2364 KB Output is correct
7 Correct 3 ms 2360 KB Output is correct
8 Correct 2 ms 2352 KB Output is correct
9 Correct 14 ms 10488 KB Output is correct
10 Correct 13 ms 10480 KB Output is correct
11 Correct 15 ms 10384 KB Output is correct
12 Correct 0 ms 792 KB Output is correct
13 Correct 1 ms 784 KB Output is correct
14 Correct 0 ms 800 KB Output is correct
15 Correct 1 ms 780 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 8652 KB Output is correct
2 Correct 22 ms 8864 KB Output is correct
3 Correct 25 ms 8544 KB Output is correct
4 Correct 16 ms 4264 KB Output is correct
5 Correct 16 ms 9480 KB Output is correct
6 Correct 15 ms 5840 KB Output is correct
7 Correct 14 ms 5868 KB Output is correct
8 Correct 13 ms 6636 KB Output is correct
9 Correct 14 ms 6612 KB Output is correct
10 Correct 13 ms 4580 KB Output is correct
11 Correct 12 ms 4580 KB Output is correct
12 Correct 11 ms 4060 KB Output is correct
13 Correct 15 ms 4048 KB Output is correct
14 Correct 13 ms 4320 KB Output is correct
15 Correct 15 ms 4332 KB Output is correct
16 Correct 11 ms 4324 KB Output is correct
17 Correct 13 ms 4332 KB Output is correct
18 Correct 12 ms 4372 KB Output is correct
19 Correct 12 ms 4332 KB Output is correct
20 Correct 13 ms 7400 KB Output is correct
21 Correct 13 ms 7400 KB Output is correct
22 Correct 15 ms 6648 KB Output is correct
23 Correct 13 ms 6444 KB Output is correct
24 Correct 14 ms 7412 KB Output is correct
25 Correct 14 ms 6372 KB Output is correct
26 Correct 13 ms 6112 KB Output is correct
27 Correct 15 ms 7404 KB Output is correct
28 Correct 17 ms 6376 KB Output is correct
29 Correct 14 ms 5336 KB Output is correct
30 Correct 17 ms 5852 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 8560 KB Output is correct
2 Correct 22 ms 8564 KB Output is correct
3 Correct 20 ms 8908 KB Output is correct
4 Correct 12 ms 4324 KB Output is correct
5 Correct 15 ms 9440 KB Output is correct
6 Correct 16 ms 6376 KB Output is correct
7 Correct 14 ms 6900 KB Output is correct
8 Correct 13 ms 5976 KB Output is correct
9 Correct 14 ms 6380 KB Output is correct
10 Correct 11 ms 4588 KB Output is correct
11 Correct 12 ms 4588 KB Output is correct
12 Correct 11 ms 4056 KB Output is correct
13 Correct 11 ms 4060 KB Output is correct
14 Correct 11 ms 4320 KB Output is correct
15 Correct 12 ms 4332 KB Output is correct
16 Correct 12 ms 4324 KB Output is correct
17 Correct 14 ms 4268 KB Output is correct
18 Incorrect 12 ms 4328 KB Output isn't correct
19 Halted 0 ms 0 KB -