답안 #1049555

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1049555 2024-08-08T22:43:01 Z 0npata Sprinkler (JOI22_sprinkler) C++17
3 / 100
4000 ms 605420 KB
#include<bits/stdc++.h>
using namespace std;

#define int long long
#define vec vector
#define hmap unordered_map

const int MXN = 200'005;
int N, L;
int H[MXN];

bool is_centr[MXN*3];
vec<int> tree[MXN*3];
set<int> tree_i[MXN*3];
int fi = MXN;
bool wn[MXN*3];

const int weight(int u, int v) {
	if(u>v)  swap(u, v);
	if(v < MXN) return 1;
	if(u >= MXN) return 0;
	return wn[v];
}

struct FenwickNode {
    int mul = 1;

    FenwickNode merge(FenwickNode other) {
        return {(mul * other.mul) % L};
    }
};


class FenwickTree {
public:
    int n;
    FenwickTree(int size) : n(size), tree(size + 1) {}

    void upd(int index, FenwickNode value) {
		index = n-index;
        while (index <= n) {
            tree[index] = tree[index].merge(value);
            index += index & -index;
        }
    }

    FenwickNode query_suffix(int index) {
		index = n-index;
        FenwickNode result{};
        while (index > 0) {
            result = tree[index].merge(result);
            index -= index & -index;
        }
        return result;
    }

    std::vector<FenwickNode> tree;
};

struct Centroid {
	vec<FenwickTree> subtree_contrs{};
	hmap<int, int> subtree_inds;
	hmap<int, int> dists;
	int root;
	int size;
	FenwickTree contr;
	int mxd = 0;

	Centroid() : contr(1) {}

	Centroid(int root, int size) : root(root), size(size), contr(size+1) {
		is_centr[root] = true;
		subtree_inds[root] = -1;
		if(root < N) contr.upd(0, {H[root]});
		dists[root] = 0;

		int si = 0;
		for(int u : tree[root]) {
			if(is_centr[u]) continue;

			dfs_init(u, root, weight(u, root), si++);
		}

		for(int i = 0; i<si; i++) {
			subtree_contrs.push_back(FenwickTree(mxd+1));
		}
	}

	void dfs_init(int u, int p, int d, int s_i) {
		if(is_centr[u]) return;
		subtree_inds[u] = s_i;
		dists[u] = d;
		mxd = max(mxd, d);
		for(int v : tree[u]) {
			if(v == p) continue;
			dfs_init(v, u, d+weight(v, u), s_i);
		}
	}
};

Centroid centroids[MXN*3];
int centroid_pars[MXN*3];
int subtree_sz[MXN*3];

void comp_subtree_sz(int u, int p = -1) {
	if(is_centr[u]) {
		subtree_sz[u] = 0;
		return;
	}
	subtree_sz[u] = 1;
	for(int v : tree[u]) {
		if(v == p) continue;
		comp_subtree_sz(v, u);
		subtree_sz[u] += subtree_sz[v];
	}
}

int find_centroid(int u, int p, int mxsz) {
	for(int v : tree[u]) {
		if(v == p) continue;
		if(subtree_sz[v] > mxsz) return find_centroid(v, u, mxsz);
	}
	return u;
}

void decompose(int u, int p = -1) {
	if(is_centr[u]) return;
	comp_subtree_sz(u);
	int v = find_centroid(u, -1, subtree_sz[u]/2);
	///cerr << "initializing centroid: " << v << '\n';
	centroid_pars[v] = p;
	centroids[v] = Centroid(v, subtree_sz[u]);
	for(int w : tree[v]) {
		decompose(w, v);
	}
}

void make_tree_binary(int u, int p = -1) {
	vec<int> ch{};
	for(int v : tree_i[u]) {
		if(v==p) continue;
		ch.push_back(v);
	}
	if(ch.size() > 2) {
		int p2 = 1;
		while(p2 < ch.size()) {
			p2 *= 2;
		}
		int root = fi;
		tree_i[u].insert(root);
		tree_i[root].insert(u);
		for(int i = 2; i<p2; i++) {
			tree_i[i/2+fi-1].insert(i+fi-1);
			tree_i[i+fi-1].insert(i/2+fi-1);
		}
		for(int i = p2; i<p2+ch.size(); i++) {
			tree_i[i/2+fi-1].insert(ch[i-p2]);
			tree_i[ch[i-p2]].insert(i/2+fi-1);
			wn[i/2+fi-1] = 1;
			tree_i[ch[i-p2]].erase(u);
			tree_i[u].erase(ch[i-p2]);
		}
		fi += p2-1;
	}
	for(int v : tree[u]) {
		if(v == p) continue;
		make_tree_binary(v, u);
	}
}



int32_t main() {
	cin >> N >> L;
	for(int i = 0; i<N-1; i++) {
		int u, v;
		cin >> u >> v;
		u--;v--;
		tree_i[u].insert(v);
		tree_i[v].insert(u);
	}
	for(int i = 0; i<N; i++) {
		cin >> H[i];
	}

	auto start = chrono::high_resolution_clock::now();
	make_tree_binary(0);
	if(false) {
	for(int i = 0; i<MXN*3; i++) {
		if(tree[i].size() > 0) {
			cerr << i << ":" << ' ';
			for(int v : tree[i]) cerr << v << ' ';
			cerr << '\n';
		}
	}
	}
	for(int i = 0; i<MXN*3; i++) {
		tree[i] = vec<int>(tree_i[i].begin(), tree_i[i].end());
	}
	auto stop = chrono::high_resolution_clock::now();
	auto duration = chrono::duration_cast<chrono::milliseconds>(stop-start).count();
	cerr << "Binary tree making took: " << duration << " milliseconds" << '\n';


	start = chrono::high_resolution_clock::now();
	decompose(0);

	stop = chrono::high_resolution_clock::now();
	duration = chrono::duration_cast<chrono::milliseconds>(stop-start).count();
	cerr << "Centroid decomposition: " << duration << " milliseconds" << '\n';

	int Q;
	cin >> Q;
	while(Q--) {
	//cerr << "HERE0" << '\n';
		int t;
		cin >> t;
		if(t == 2) {
		//cerr << "Here1" << '\n';
			int u;
			cin >> u;
			u--;
			int ans = 1;
			int ci = u;
			auto mult_ans = [&](int val) {
				ans *= val;
				ans %= L;
			};
			while(ci != -1) {
				int d = centroids[ci].dists[u];
				mult_ans(centroids[ci].contr.query_suffix(d).mul);

				for(int i = 0; i<centroids[ci].subtree_contrs.size(); i++) {
					if(centroids[ci].subtree_inds[u] != i) {
						mult_ans(centroids[ci].subtree_contrs[i].query_suffix(d).mul);
					}
				}

				ci = centroid_pars[ci];
				//cerr << ci << '\n';
			};
			cout << ans << '\n';
		}
		else {
			//cerr <<"HERE2" << '\n';
			int u, d, w;
			cin >> u >> d >> w;
			u--;
			centroids[u].contr.upd(min(centroids[u].contr.n-1, d), {w});
			int ci = centroid_pars[u];
			while(ci != -1) {
				//cerr << "Cur Centroid: " << ci << '\n';
				auto& c = centroids[ci];
				int contr_d = d - c.dists[u];
				if(contr_d < 0) {
					ci = centroid_pars[ci];
					continue;
				}
				auto& st = c.subtree_contrs[c.subtree_inds[u]];
				contr_d = min(contr_d, st.n-1);
				//cerr << st.n << '\n';
				st.upd(contr_d, {w});

				ci = centroid_pars[ci];
				//cerr << ci << '\n';
			}
		}
	}


}

Compilation message

sprinkler.cpp: In function 'void make_tree_binary(long long int, long long int)':
sprinkler.cpp:146:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  146 |   while(p2 < ch.size()) {
      |         ~~~^~~~~~~~~~~
sprinkler.cpp:156:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'long long unsigned int' [-Wsign-compare]
  156 |   for(int i = p2; i<p2+ch.size(); i++) {
      |                   ~^~~~~~~~~~~~~
sprinkler.cpp: In function 'int32_t main()':
sprinkler.cpp:233:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<FenwickTree>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  233 |     for(int i = 0; i<centroids[ci].subtree_contrs.size(); i++) {
      |                    ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 42 ms 176976 KB Output is correct
2 Correct 49 ms 176980 KB Output is correct
3 Correct 44 ms 177124 KB Output is correct
4 Correct 44 ms 178524 KB Output is correct
5 Correct 44 ms 178260 KB Output is correct
6 Correct 43 ms 178000 KB Output is correct
7 Correct 42 ms 178008 KB Output is correct
8 Correct 45 ms 177748 KB Output is correct
9 Correct 41 ms 177244 KB Output is correct
10 Correct 41 ms 177024 KB Output is correct
11 Correct 41 ms 177232 KB Output is correct
12 Correct 46 ms 177232 KB Output is correct
13 Correct 41 ms 177232 KB Output is correct
14 Correct 41 ms 177232 KB Output is correct
15 Correct 40 ms 177172 KB Output is correct
16 Correct 43 ms 176980 KB Output is correct
17 Correct 44 ms 176984 KB Output is correct
18 Correct 41 ms 177232 KB Output is correct
19 Correct 42 ms 177124 KB Output is correct
20 Correct 41 ms 177124 KB Output is correct
21 Correct 40 ms 176976 KB Output is correct
22 Correct 43 ms 177124 KB Output is correct
23 Correct 42 ms 177080 KB Output is correct
24 Correct 49 ms 177244 KB Output is correct
25 Correct 46 ms 176976 KB Output is correct
26 Correct 42 ms 177116 KB Output is correct
27 Correct 40 ms 177036 KB Output is correct
28 Correct 41 ms 177240 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 41 ms 177240 KB Output is correct
2 Correct 3641 ms 501916 KB Output is correct
3 Correct 2031 ms 502348 KB Output is correct
4 Correct 3391 ms 605420 KB Output is correct
5 Correct 2795 ms 501928 KB Output is correct
6 Correct 2381 ms 448812 KB Output is correct
7 Correct 2200 ms 424248 KB Output is correct
8 Execution timed out 4046 ms 300948 KB Time limit exceeded
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 41 ms 177240 KB Output is correct
2 Correct 3641 ms 501916 KB Output is correct
3 Correct 2031 ms 502348 KB Output is correct
4 Correct 3391 ms 605420 KB Output is correct
5 Correct 2795 ms 501928 KB Output is correct
6 Correct 2381 ms 448812 KB Output is correct
7 Correct 2200 ms 424248 KB Output is correct
8 Execution timed out 4046 ms 300948 KB Time limit exceeded
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 40 ms 177244 KB Output is correct
2 Execution timed out 4098 ms 599084 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 44 ms 176976 KB Output is correct
2 Execution timed out 4072 ms 597756 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 42 ms 176976 KB Output is correct
2 Correct 49 ms 176980 KB Output is correct
3 Correct 44 ms 177124 KB Output is correct
4 Correct 44 ms 178524 KB Output is correct
5 Correct 44 ms 178260 KB Output is correct
6 Correct 43 ms 178000 KB Output is correct
7 Correct 42 ms 178008 KB Output is correct
8 Correct 45 ms 177748 KB Output is correct
9 Correct 41 ms 177244 KB Output is correct
10 Correct 41 ms 177024 KB Output is correct
11 Correct 41 ms 177232 KB Output is correct
12 Correct 46 ms 177232 KB Output is correct
13 Correct 41 ms 177232 KB Output is correct
14 Correct 41 ms 177232 KB Output is correct
15 Correct 40 ms 177172 KB Output is correct
16 Correct 43 ms 176980 KB Output is correct
17 Correct 44 ms 176984 KB Output is correct
18 Correct 41 ms 177232 KB Output is correct
19 Correct 42 ms 177124 KB Output is correct
20 Correct 41 ms 177124 KB Output is correct
21 Correct 40 ms 176976 KB Output is correct
22 Correct 43 ms 177124 KB Output is correct
23 Correct 42 ms 177080 KB Output is correct
24 Correct 49 ms 177244 KB Output is correct
25 Correct 46 ms 176976 KB Output is correct
26 Correct 42 ms 177116 KB Output is correct
27 Correct 40 ms 177036 KB Output is correct
28 Correct 41 ms 177240 KB Output is correct
29 Correct 41 ms 177240 KB Output is correct
30 Correct 3641 ms 501916 KB Output is correct
31 Correct 2031 ms 502348 KB Output is correct
32 Correct 3391 ms 605420 KB Output is correct
33 Correct 2795 ms 501928 KB Output is correct
34 Correct 2381 ms 448812 KB Output is correct
35 Correct 2200 ms 424248 KB Output is correct
36 Execution timed out 4046 ms 300948 KB Time limit exceeded
37 Halted 0 ms 0 KB -