This world need more Zhu

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 454    Accepted Submission(s): 84

Problem Description

As we all know, Zhu is the most powerful man. He has the infinite power to protest the world. We need more men like Zhu!

In Duoladuo, this place is like a tree. There are n vertices and n−1 edges. And the root is 1. Each vertex can reached by any other vertices. Each vertex has a people with value Ai named Zhu's believer.

Liao is a curious baby, he has m questions to ask Zhu. But now Zhu is busy, he wants you to help him answer Liao's questions.

Liao's question will be like "u v k".

That means Liao want to know the answer from following code:

ans = 0; cnt = 0;

for x in the shortest path from u to v {

cnt++;
    
    if(cnt mod k == 0) ans = max(ans,a[x]);

}

print(ans).

Please read the hints for more details.

 

Input

In the first line contains a single positive integer T, indicating number of test case.

In the second line there are two numbers n, m. n is the size of Duoladuo, m is the number of Liao's questions.

The next line contains n integers A1,A2,...An, means the value of ith vertex.

In the next n−1 line contains tow numbers u, v. It means there is an edge between vertex u and vertex v.

The next m lines will be the Liao's question:

u v k

1≤T≤10,1≤n≤100000,1≤m≤100000,1≤u,v≤n,1≤k, Ai≤1000000000.

 

Output

For each case, output Case #i: (i is the number of the test case, from 1 to T).

Then, you need to output the answer for every Liao's questions.

 

Sample Input

1
5 5
1 2 4 1 2
1 2
2 3
3 4
4 5
1 1 1
1 3 2
1 3 100
1 5 2
1 3 1
 

Sample Output

Case #1:
1
2
0
2
4

Hint

In query 1,there are only one vertex in the path,so the answer is 1.

In query 2,there are three vertices in the path.But only the vertex 2 mod 2 equals to 0.

In query 3,there are three vertices in the path.But no vertices mod 100 equal to 0.

In query 4,there are five vertices in the path.There are two vertices mod 2 equal to 0.So the answer is max(a[2],a[4]) = 2.

In query 5,there are three vertices in the path.And all the vertices mod 1 equal to 0. So the answer is a[3] = 4.

 

Author

UESTC
 

Source

 
 //2017-08-08
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define lson (id<<1)
#define rson ((id<<1)|1) using namespace std; const int N = ;
const int LEN = ;//块的大小
vector<int> G[N];
int n, m, label, answer[N]; //树链剖分
int arr[N];//arr[i]表示节点i的权值
int fa[N];//fa[i]表示节点i的父亲
int son[N];//son[i]表示节点i的重儿子
int top[N];//top[i]表示节点i所在重链的顶端节点
int size[N];//size[i]表示以节点i为根的子树的节点数
int deep[N];//deep[i]表示节点i的深度
int postion[N];//postion[i]表示节点i在线段树中的位置
int trID[N];//trID[i]表示节点i在剖分后的新编号 void dfs1(int u, int father){
fa[u] = father;
son[u] = ;
size[u] = ;
for(auto v: G[u]){
if(v == father)continue;
deep[v] = deep[u]+;
dfs1(v, u);
size[u] += size[v];
if(size[v] > size[son[u]])
son[u] = v;
}
} void dfs2(int u, int ancestor){
top[u] = ancestor;
postion[u] = ++label;
trID[label] = u;
if(son[u])
dfs2(son[u], ancestor);
for(auto v: G[u]){
if(v == fa[u] || v == son[u])
continue;
dfs2(v, v);
}
} //最近公共祖先
inline int lca(int u, int v){
while(top[u] ^ top[v]){
if(deep[top[u]] < deep[top[v]])
swap(u, v);
u = fa[top[u]];
}
return deep[u] < deep[v] ? u : v;
} //线段树
struct Node{
int l, r, v;
}tree[N<<];
int nS[N], qL[N], qR[N]; void build(int id, int l , int r){
tree[id].l = l;
tree[id].r = r;
if(l == r){
tree[id].v = arr[trID[nS[l]]];
return;
}
int mid = (l+r)>>;
build(lson, l, mid);
build(rson, mid+, r);
tree[id].v = max(tree[lson].v, tree[rson].v);
} int query(int id, int l, int r){
if(tree[id].l == l && tree[id].r == r)
return tree[id].v;
int mid = (tree[id].l+tree[id].r)>>;
if(l > mid)return query(rson, l, r);
if(r <= mid)return query(lson, l, r);
return max(query(lson, l, mid), query(rson, mid+, r));
} inline int cal(int l, int r, int k){
if(qL[k] > qR[k])return ;
l = lower_bound(nS+qL[k], nS+qR[k]+, l)-nS;
r = upper_bound(nS+qL[k], nS+qR[k]+, r)-nS-;
if(l <= r)return query(, l, r);
else return ;
} int question(int u, int v, int k){
int ans = -, f = lca(u, v);
int uk = (deep[u] + )%k;
int vk = (deep[f] + (k - (deep[u]-deep[f]+)%k)) % k;
while(top[u] ^ top[v]){
if(deep[top[u]] > deep[top[v]]){
ans = max(ans, cal(postion[top[u]], postion[u], uk));
u = fa[top[u]];
}else{
ans = max(ans, cal(postion[top[v]], postion[v], vk));
v = fa[top[v]];
}
}
if(deep[u] > deep[v])
ans = max(ans, cal(postion[v], postion[u], uk));
else
ans = max(ans, cal(postion[u], postion[v], vk));
return ans;
} vector<int> block[LEN];
vector< pair< pair<int, int>, int > > qs[LEN+];
vector< pair< pair<int, int>, pair<int, int> > > qy[N];
void solve(int k){
for(int i = ; i <= n; i++){
int u = trID[i];
block[deep[u]%k].push_back(u);
}
label = ;
for(int i = ; i < k; i++){
qL[i] = label + ;
for(auto x: block[i])
nS[++label] = postion[x];
qR[i] = label;
}
build(, , n);
for(auto &x: qs[k])
answer[x.second] = question(x.first.first, x.first.second, k);
for(int i = ; i < k; i++)
block[i].clear();
qs[k].clear();
} int sk[N], tp;//sk为栈, tp为栈顶指针 void dfs(int u){
sk[++tp] = u;
for(auto &x: qy[u]){
for(int i = tp-x.first.second;
i > && deep[sk[i]] >= deep[x.first.first];
i -= x.second.first)
answer[x.second.second] = max(answer[x.second.second], arr[sk[i]]);
}
qy[u].clear();
for(auto v : G[u]){
if(v ^ fa[u])
dfs(v);
}
--tp;
} int main()
{
//freopen("dataB.txt", "r", stdin);
int T, kase = ;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++)
scanf("%d", &arr[i]);
int u, v, k;
for(int i = ; i <= n; i++)
G[i].clear();
for(int i = ; i <= n-; i++){
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
label = ;
dfs1(, );
dfs2(, );
//debug();
for(int i = ; i < m; i++){
scanf("%d%d%d", &u, &v, &k);
if(k >= LEN){
int f = lca(u, v);
int d = (deep[u]+deep[v]-*deep[f]+)%k;
if(u ^ f)
qy[u].push_back({ {f, k-}, {k, i} });
if(v ^ f)
qy[v].push_back({ {f, d}, {k, i} });
}else{
qs[k].push_back({ {u, v}, i });
}
}
memset(answer, , sizeof(answer));
for(int i = ; i < LEN; i++)
if(qs[i].size())
solve(i);
tp = ;
dfs();
printf("Case #%d:\n", ++kase);
for(int i = ; i < m; i++)
printf("%d\n", answer[i]);
} return ;
}

HDU5840(SummerTrainingDay08-B 树链剖分+分块)的更多相关文章

  1. UOJ#435. 【集训队作业2018】Simple Tree 树链剖分,分块

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ435.html 前言 分块题果然是我这种蒟蒻写不动的.由于种种原因,我写代码的时候打错了很多东西,最致命的是数组开小了.* ...

  2. HDU5840 (分块+树链剖分)

    Problem This world need more Zhu 题目大意 给一颗n个点的有点权的树,有m个询问,对于每个询问u,v,k,首先将点u到点v的最短路径上的所有点按顺序编号,u的编号为1, ...

  3. 【块状树】【树链剖分】bzoj1036 [ZJOI2008]树的统计Count

    很早之前用树链剖分写过,但是代码太长太难写,省选现场就写错了. #include<cstdio> #include<algorithm> #include<cstring ...

  4. jzoj5987. 【WC2019模拟2019.1.4】仙人掌毒题 (树链剖分+概率期望+容斥)

    题面 题解 又一道全场切的题目我连题目都没看懂--细节真多-- 先考虑怎么维护仙人掌.在线可以用LCT,或者像我代码里先离线,并按时间求出一棵最小生成树(或者一个森林),然后树链剖分.如果一条边不是生 ...

  5. 【树链剖分 差分】bzoj3626: [LNOI2014]LCA

    把LCA深度转化的那一步还是挺妙的.之后就是差分加大力数据结构了. Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep ...

  6. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  7. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  8. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  9. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

随机推荐

  1. Python中super()的用法

    参考链接:https://www.cnblogs.com/shengulong/p/7892266.html super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是 ...

  2. 协程 coroutine

    参考链接: http://manual.luaer.cn/2.11.html http://www.cnblogs.com/riceball/archive/2008/01/03/1025158.ht ...

  3. 使用 kafkat 在线扩缩容 kafka replicas

    本文档应用环境为 kafka-0.8.2.0, 其余版本请先行测试 场景 线上很多 kafka 的 topic 的副本数为1,这样的设置丧失了 kafka 高可用的特性,所以我们需要把 topic 的 ...

  4. 利用koa打造restful API

    概述 最近学习利用koa搭建API接口,小有所得,现在记录下来,供以后开发时参考,相信对其他人也有用. 就目前我所知道的而言,API有2种,一种是jsonp这种API,前端通过ajax来进行跨域请求获 ...

  5. Tools - 文本编辑器Notepad++

    00 - NotePad++ 官网 01 - Notepad++修改主题 依次点击设置---语言格式设置---选择主题,在显示界面中修改相关设置(背景色.前景色.字体等). 02 - Notepad+ ...

  6. nginx发布静态网页

    http://www.jb51.net/article/71384.htm 切记不要把项目放在/root下 会出现 nginx open() "" failed (13: Perm ...

  7. TensorFlow.js之根据数据拟合曲线

    这篇文章中,我们将使用TensorFlow.js来根据数据拟合曲线.即使用多项式产生数据然后再改变其中某些数据(点),然后我们会训练模型来找到用于产生这些数据的多项式的系数.简单的说,就是给一些在二维 ...

  8. sftp命令不被识别

    sftp命令不被识别 原因:C:\Windows\System32文件夹下面没有sftp可执行程序 解决方案:安装openssh,安装完成之后可发现在path系统变量的值中多了openssh的安装目录 ...

  9. Redis 3.2.4集群实战

    一.Redis Cluster集群设计Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis3.0之后版本支持Redis-Cluster集群,Redis-Cluster采用无中心 ...

  10. spring scope 作用域

    转自:http://www.cnblogs.com/qq78292959/p/3716827.html 今天研究了一下scope的作用域.默认是单例模式,即scope="singleton& ...