比赛 20161116 评测结果 AAAAAAAAAA
题目名称 新型武器 最终得分 100
用户昵称 Fmuckss 运行时间 1.161 s
代码语言 C++ 内存使用 120.48 MiB
提交时间 2016-11-16 11:52:16
显示代码纯文本
#include <iostream>
#include <cstdio> 
#include <cmath>
#include <queue>
using namespace std;
const int maxn = 3e5 + 1;

#define is_num(x) (x <= '9' and x >= '0')
inline int get_num() {
	char tmp = getchar();
	int res = 0;
	
	while (not is_num(tmp)) tmp = getchar();
	while (    is_num(tmp)) {
		res = (res << 3) + (res << 1) + tmp - '0';
		tmp = getchar();
	}
	
	return res;
}


int a[maxn];
int tot_v[93][maxn];
int v[maxn];
int sn, n, q;

int dfn[maxn], nfd[maxn], end[maxn], tcnt;
int de[maxn], belong[maxn];
int deg[maxn], root;
int mx_de;

struct Edge {
	int to, ne;
	Edge() {}
	Edge(int to_, int ne_) { to = to_, ne = ne_; }
} e[maxn];
int head[maxn], ecnt;
inline void add_edge(int fr, int to) {
	e[++ecnt] = Edge(to, head[fr]), head[fr] = ecnt;
	deg[to]++;
}

void dfs(int now, int fa) {
	dfn[now] = ++tcnt;
	nfd[tcnt] = now;
	mx_de = max(mx_de, de[now]); 
	
	for (int i = head[now]; i; i = e[i].ne) {
		int to = e[i].to;
		if (to == fa) continue;
		
		de[to] = de[now] + 1;
		dfs(to, now);
	}
	
	end[now] = tcnt;
}

inline void modify(int tar, int to) {
	int outree = dfn[tar];
	int ori = v[outree];
	
	tot_v[belong[outree]][de[tar]] += to - ori;
	v[outree] = to;
} 

int v_tmp[maxn];

inline int query(int tar, int deep) {
	if (deep >= n) return 0;
	
	int ans = 0;
	int l = dfn[tar], r = end[tar], top;
	int bl = belong[l], br = belong[r];
	
	if (bl == br) {
		for (int i = l ; i <= r; i++) if (de[nfd[i]] == deep) ans += v[i];
		return ans;
	} 
	
	top = bl * sn;
	if (l != top - sn + 1) {
		for (int i = l; i <= top; i++) if (de[nfd[i]] == deep) ans += v[i];
		bl++;
	}
	top = br * sn;
	if (r != top) {
		for (int i = top - sn + 1; i <= r; i++) if (de[nfd[i]] == deep) ans += v[i];
		br--;
	}
	for (int i = bl; i <= br; i++) ans += tot_v[i][deep];
	
	return ans;
}

inline void init() {
	for (int i = 1; i <= n; i++) if (not deg[i]) root = i;
	de[root] = 1;
	dfs(root, 0);
	for (int i = 1; i <= n; i++) v[dfn[i]] = a[i];
	
	if (n >= 3e5) sn = 3333;
	else sn = sqrt(n);
	int nblk = 1, cnt = 0;
	
	for (int i = 1; i <= n; i++) {
		tot_v[nblk][de[nfd[i]]] += v[i];
		belong[i] = nblk;
		
		if (++cnt == sn) cnt = 0, nblk++; 
	}
}

inline void read() {
	n = get_num();
	for (int i = 1; i <= n; i++) a[i] = get_num();
	for (int i = 1; i <= n - 1; i++) {
		int fr = get_num(), to = get_num();
		add_edge(fr, to);
	}
}

void out(int tar, int deep) {
	queue<int> q;
	int now_de = 0;
	q.push(tar);
	int now;
	
	while (not q.empty()) {
		now = q.front(); q.pop();
		if (now_de != de[now]) {
			printf("\n");
			now_de = de[now];
		}
		printf("%d ", now);
		
		for (int i = head[now]; i; i = e[i].ne) {
			int to = e[i].to;
			if (de[to] <= de[tar] || de[to] > de[now] + deep) continue;
			q.push(to);
		}
	}
}

inline void solve() {
	q = get_num();
	int han, u, t;
	
	for (int i = 1; i <= q; i++) {
		han = get_num();
		u = get_num(), t = get_num();
		
		if (han == 1) modify(u, t);
		else printf("%d\n", query(u, de[u] + t));
	}
}

int main() {
	freopen("newweapon.in", "r", stdin); 
	freopen("newweapon.out", "w", stdout); 
	read();
	init();
	solve();
	return 0;
}