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. KVM虚拟机配置

    KVM 全称是 Kernel-Based Virtual Machine.也就是说 KVM 是基于 Linux 内核实现的,KVM有一个内核模块叫 kvm.ko,只用于管理虚拟 CPU 和内存. 在 ...

  2. solr 5.5使用 和pyg里 的4.10.3版 部署到tomcat中不一样(不使用内置jetty)

    http://www.cnblogs.com/zhuxiaojie/p/5764680.html

  3. iOS-项目开发1-UIImage

    UIImage+Extension /// 获取后的数据 a.length > b.length. 同时,使用UIIMageJPEGRepresnetation压缩图片,如果compressio ...

  4. Spring Cloud断路器Hystrix

    在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定.为了解决这样的问题,因此产生了断路器模式. 什么是 ...

  5. 关于如何食用Xcode——用mac的小蒟蒻

    前言QwQ 对于一只用Mac的小蒟蒻,没有Dev_c++简直太难受了,用在线IDE写代码又没法保存,那么我们怎么办呢? 好在App Store里有这个好东西 所以我们今天来介绍一下 “如何使用Xcod ...

  6. 使用.NetCore在Linux上写TCP listen 重启后无法绑定地址

    拥抱.net core的过程中, 将公司的一套java项目改成了.net core 2.0版的. 里面的tcp服务被我用msdn的SocketAsyncEventArgs方式重写了, 然而在测试的过程 ...

  7. C#:时间日期操作(持续更新)

    1.给定时间戳返回指定的时间格式 private string StampToDate(string timeStamp,string format) { DateTime dtStart = Tim ...

  8. spring-boot-starter-actuator

    首先在pom中添加依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xml ...

  9. 多线程编程——ANR

    1.为什么要用多线程 这里列出几个原因: 提高用户体验或者避免ANR:在事件处理代码中需要使用多线程,否则会出现ANR(Application is not responding),或者因为响应较慢导 ...

  10. 多线程编程——java

    1.进程和线程 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号 ...