백준14288 내리 갈굼 4

문제 링크

  • http://icpc.me/14288

사용 알고리즘

  • FenwickTree

시간복잡도

  • O(n + m log n)

풀이

(내리 갈굼 2)와 (내리 갈굼 3)을 적절하게 잘 섞어주면 됩니다.

전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <bits/stdc++.h>
using namespace std;

int n, m, in[101010], out[101010], cnt;
vector<int> g[101010];

struct BIT{
	int tree[101010];
	void update(int x, int val){
		for(int i=x; i<=n; i += (i&-i)){
			tree[i] += val;
		}
	}
	int query(int x){
		int ret = 0;
		for(int i=x; i>0; i -= (i&-i)){
			ret += tree[i];
		}
		return ret;
	}
} up, down;

int dfs(int v){
	in[v] = ++cnt;
	for(auto u : g[v]){
		dfs(u);
	}
	out[v] = cnt;
}


int main(){
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;

	for(int i=1; i<=n; i++){
		int t; cin >> t;
		if(i == 1) continue;
		g[t].push_back(i);
	}

	dfs(1);

	int flag = 0;
	while(m--){
		int op, x, y; cin >> op;
		if(op == 3) flag ^= 1;
		else if(op == 1){
			cin >> x >> y;
			if(!flag) down.update(in[x], y), down.update(out[x]+1, -y);
			else up.update(in[x], y);
		}else{
			cin >> x;
			int u = up.query(out[x]) - up.query(in[x]-1);
			int d = down.query(in[x]);
			cout << u+d << "\n";
		}
	}
}