Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't want to take any help from the Genie because he thought that it might be another adventure for him. All he remembered was the paths he had taken to reach there. But since he took the lamp, all the genies in the cave became angry and they were planning to attack. As Aladdin was not afraid, he wondered how many genies were there. He summoned the Genie from the lamp and asked this.

Now you are given a similar problem. For simplicity assume that, you are given a tree (a connected graph with no cycles) with n nodes, nodes represent places, edges represent roads. In each node, initially there are an arbitrary number of genies. But the numbers of genies change in time. So, you are given a tree, the number of genies in each node and several queries of two types. They are:

1)      0 i j, it means that you have to find the total number of genies in the nodes that occur in path from node i to j (0 ≤ i, j < n).

2)      1 i v, it means that number of genies in node i is changed to v (0 ≤ i < n, 0 ≤ v ≤ 1000).

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case starts with a blank line. Next line contains an integer n (2 ≤ n ≤ 30000). The next line contains n space separated integers between 0 and 1000, denoting the number of genies in the nodes respectively. Then there are n-1 lines each containing two integers: u v (0 ≤ u, v < n, u ≠ v) meaning that there is an edge from node u and v. Assume that the edges form a valid tree. Next line contains an integer q (1 ≤ q ≤ 105) followed by q lines each containing a query as described above.

Output

For each case, print the case number in a single line. Then for each query 0 i j, print the total number of genies in the nodes that occur in path i to j.

Sample Input

1

4

10 20 30 40

0 1

1 2

1 3

3

0 2 3

1 1 100

0 2 3

Sample Output

Case 1:

90

170

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
using namespace std;
typedef long long ll;
const int N=2e5+;
const int M=N*N+;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N],c[N]; //top 最近的重链父节点
int num,n,m;
vector<int> v[N];
struct tree {
int x,y;
void read() {
scanf("%d%d",&x,&y);
}
};
tree e[N];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == f) continue;
dfs1(ff, u, d + );
siz[u] += siz[ff];
if (siz[son[u]] < siz[ff])
son[u] = ff;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == fa[u] || ff == son[u]) continue;
dfs2(ff, ff);
}
} struct Tree {
int l,r,val,sum;
};
Tree tree[*N];
void pushup(int x) {
tree[x].val = max(tree[lson(x)].val, tree[rson(x)].val);
tree[x].sum=tree[lson(x)].sum+tree[rson(x)].sum;
} void build(int l,int r,int v) {
tree[v].l=l;
tree[v].r=r;
if(l==r) {
tree[v].val = val[l];
tree[v].sum=val[l];
return ;
}
int mid=(l+r)>>;
build(l,mid,v*);
build(mid+,r,v*+);
pushup(v);
}
void update(int o,int v,int val) { //log(n)
if(tree[o].l==tree[o].r) {
tree[o].val =tree[o].sum= val;
return ;
}
int mid = (tree[o].l+tree[o].r)/;
if(v<=mid)
update(o*,v,val);
else
update(o*+,v,val);
pushup(o);
}
int querySum(int x,int l,int r) {
if (tree[x].l >= l && tree[x].r <= r) {
return tree[x].sum;
}
int mid = (tree[x].l + tree[x].r) / ;
int ans = ;
if (l <= mid) ans += querySum(lson(x),l,r);
if (r > mid) ans += querySum(rson(x),l,r);
return ans;
}
int Qsum(int u,int v) {
int tp1 = top[u], tp2 = top[v];
int ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans +=querySum(,id[tp1], id[u]);
//printf("ans: %d\n",ans);
u = fa[tp1];
tp1 = top[u];
}
//if (u == v) return ans;
if (dep[u] > dep[v]) swap(u, v);
ans +=querySum(,id[u], id[v]);
return ans;
}
void init(){
for(int i=;i<N;i++)v[i].clear();
met(tree,);met(son,);met(val,);
}
int main() {
int t,T=;
scanf("%d",&t);
while(t--) {
init();
++T;
scanf("%d",&n);
for(int i=; i<=n; i++)scanf("%d",&c[i]);
for(int i=; i<n; i++) {
e[i].read();
e[i].x++;e[i].y++;
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
} num = ;
dfs1(,,);
dfs2(,);
for (int i = ; i <=n; i++) {
val[id[i]] = c[i];
}
build(,num,);
char s[];
scanf("%d",&m);
printf("Case %d:\n",T);
while(m--) {
int o,x,y;
scanf("%d",&o);
scanf("%d%d",&x,&y);
if (o)
x++,update(,id[x],y);
else
x++,y++,printf("%d\n",Qsum(x,y));
}
}
return ;
}

Lightoj 1348 Aladdin and the Return Journey (树链剖分)(线段树单点修改区间求和)的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. python学习总结---面向对象2

    面向对象三大特点 - 封装:既是对数据结构的封装,有是处理数据的方法的封装. - 继承:强调的父子类的关系. - 多态:不同对象调用相同的方法,有不同的响应. 类的继承 - 相关概念 - 继承:父类的 ...

  2. python学习总结---函数使用 and 装饰器

    # 函数使用 ### 零碎知识 - 灵活的if-else ```python a = 3 if False else 5 print(a) ''' if False: a = 3 else: a = ...

  3. HDU 4655 Cut Pieces 找规律+简单计数

    解法参考:http://blog.csdn.net/a601025382s/article/details/9840125 #include <cstdio> #include <c ...

  4. GridView与ListView冲突

    由于GridView与listView都是继承自ScrollView,所以两个控件放在一起时需要重写控件方法   public class MyGridView extends GridView{  ...

  5. 使用pl/sql在oracle中新建表和对应序列

    1.登录后再Table节点右键新建表: 开始编辑表结构 列 键约束 检查约束 查看sql,没问题的话点击应用,创建表 2.创建序列sequence,在Sequence节点右键新建 填写内容 查看sql ...

  6. vue.$refs 的用法

    官网给出的解释是: 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上. 1.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素; 2.如果用在子组件上,引用 ...

  7. 【bzoj1706】[usaco2007 Nov]relays 奶牛接力跑 离散化+倍增Floyd

    题目描述 FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T <= 100) ...

  8. DataBase -- Count & Group by

    SQL Count()函数: SQL COUNT(column_name)语法:COUNT(column_name)函数返回指定列的值得数目(NULL不计入) select count(column_ ...

  9. redux-saga call 和 fork的区别

    call 为阻塞调用, fork为非阻塞调用

  10. <a></a>的href属性失效

    <a href="javascript:void(0);" class="close">关闭</a>