题目描述 Description
方方方种下了三棵树,两年后,第二棵树长出了 n n n个节点,其中 1 1 1号节点是根节点。
方方方进行 m m m次操作,每个操作为:
(1)给出两个数 i i i, x x x,将第 i i i个节点的子树中,与 i i i距离为斐波那契数的节点权值 + x +x +x(包括 i i i本身) 。
(2)给出一个数 i i i,求出第 i i i个节点的子树中,与 i i i距离为斐波那契数的节点的权值和(包括 i i i本身) 。
输入 Input
第一行两个整数 n , m n,m n,m。接下来 n − 1 n-1 n−1行每行两个整数 a , b a,b a,b表示一条边。接下来 m m m行每行第一个数表示操作类型,接下来 1 1 1或 2 2 2个数表示 i ( , x ) i (,x) i(,x)。
输出 Output
对于每个(2)操作,输出一行一个整数表示答案。
样例输入 Sample Input
5 3
1 2
2 3
3 4
4 5
1 1 1
1 2 2
2 1
样例输出 Sample Output
10
限制 Limits
对于 30 % 30\% 30%的数据, n , m ≤ 1 0 3 n,m\le 10^3 n,m≤103。
对于 100 % 100\% 100%的数据, n , m ≤ 1 0 5 , ∣ x ∣ ≤ 1 0 9 n,m\le 10^5,|x|\le 10^9 n,m≤105,∣x∣≤109。
Time Limit : 1s & Memory Limit : 256MB
暴力谁都会,不说了……
观察斐波那契数列,因为它的通项公式是指数级的,指数为
1
+
5
≈
2
1+\sqrt 5\approx 2
1+5≈2,所以每次修改不多于
log
2
n
\log_2 n
log2n层,所以预处理出点
i
i
i的子树向下
f
j
f_j
fj(表示斐波那契数列的第
j
j
j项)层最左端和最右端的点,这个可以DFS解决。为了方便修改,可以对树按BFS序重标号,然后就很方便了……因为每层标号都是连续的,每次按照预处理出的信息在线段树上修改查询即可。
对于计算,发现每个数的范围是
[
−
1
0
19
,
1
0
19
]
[-10^{19},10^{19}]
[−1019,1019],long long存不下,unsigned long long没符号,所以自行实现signed long long类即可。
时间复杂度为
O
(
n
log
2
2
n
)
O(n\log_2^2 n)
O(nlog22n),大代码慎入。
Code