This world need more Zhu

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5840

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

题意

给你一棵树,然后Q次询问,每个询问给你u,v,k,问你从u到v,每次跳k步,然后路过的最大值是多少。

题解:

k大的时候,肯定XJB暴力就好了。

但是这个暴力也不能纯暴力呀,往上跳这个玩意儿得做到O1才行。

这个你就按照dfs序的顺序去维护就好了,然后下标减去k,就表示这个点往上跳了k步。

K小的时候,XJB暴力就不行了,这个就得机智一点。

我们考虑询问,其实可以把询问拆成两个,u到lca(u,v)中,deep%k=a的最大值,和v到lca(u,v)中,deep%k=b的最大值。

询问拆开之后,我们对于熟练剖分之后,把所有点%k等于相同值的点扔在一起,然后就相当于我们拆成了k棵树,每棵树的形态都是一样的。

然后我们随便拿一颗线段树莽一波就好了。

至于为什么我的块是20,大概是因为前面瞎JB暴力的常数比树链剖分的常数低吧?

【其实大概是傻逼出题人出的数据太TM水了吧?

代码

#include <bits/stdc++.h>
#define ls (o << 1)
#define rs (o << 1 | 1)
#define FI first
#define SE second
using namespace std; const int N = 100005; const int MAGIC = 20; int a[N]; vector <int> G[N]; int seq[N], tin[N], fa[N], dep[N], top[N], son[N], sz[N], label; void dfs1(int u, int father) {
fa[u] = father;
son[u] = 0; sz[u] = 1;
for(auto v : G[u]) {
if(v == father) continue;
dep[v] = dep[u] + 1;
dfs1(v, u);
sz[u] += sz[v];
if(sz[v] > sz[son[u]])
son[u] = v;
}
} void dfs2(int u, int anc) {
top[u] = anc; tin[u] = ++ label;
seq[label] = u;
if(son[u]) dfs2(son[u], anc);
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(dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
} vector < pair < pair <int, int>, int> > qs[MAGIC + 5]; int n, m, ans[N]; int nS[N], cL[N], cR[N]; struct Seg {
int l, r, v;
} T[N << 2]; void build(int o, int l, int r) {
T[o].l = l; T[o].r = r;
if(l == r) { T[o].v = a[seq[nS[l]]]; return; }
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
T[o].v = max(T[ls].v, T[rs].v);
} int query(int o, int l, int r) {
if(T[o].l == l && T[o].r == r) return T[o].v;
int mid = (T[o].l + T[o].r) >> 1;
if(r <= mid) return query(ls, l, r);
if(l > mid) return query(rs, l, r);
return max(query(ls, l, mid), query(rs, mid + 1, r));
} inline int cal(int l, int r, int k) {
if(cL[k] > cR[k]) return 0;
l = lower_bound(nS + cL[k], nS + cR[k] + 1, l) - nS;
r = upper_bound(nS + cL[k], nS + cR[k] + 1, r) - nS - 1;
return l <= r ? query(1, l, r) : 0;
} int ask(int u, int v, int k) {
int ret = -1, f = lca(u, v);
int uk = (dep[u] + 1) % k;
int vk = (dep[f] + (k - (dep[u] - dep[f] + 1) % k)) % k;
while(top[u] ^ top[v]) {
if(dep[top[u]] > dep[top[v]]) {
ret = max(ret, cal(tin[top[u]], tin[u], uk));
u = fa[top[u]];
} else {
ret = max(ret, cal(tin[top[v]], tin[v], vk));
v = fa[top[v]];
}
}
if(dep[u] > dep[v]) {
ret = max(ret, cal(tin[v], tin[u], uk));
} else {
ret = max(ret, cal(tin[u], tin[v], vk));
}
return ret;
} vector <int> E[MAGIC]; void small_case(int k) {
for(int i = 1; i <= n; ++ i) {
int u = seq[i];
E[dep[u] % k].push_back(u);
}
label = 0;
for(int i = 0; i < k; ++ i) {
cL[i] = label + 1;
for(auto x : E[i])
nS[++ label] = tin[x];
cR[i] = label;
}
build(1, 1, n);
for(auto &x : qs[k])
ans[x.SE] = ask(x.FI.FI, x.FI.SE, k);
for(int i = 0; i < k; ++ i)
E[i].clear();
qs[k].clear();
} vector < pair < pair <int, int>, pair <int, int> > > qy[N]; int sk[N], tp; void dfs(int u) {
sk[++ tp] = u;
for(auto &x : qy[u]) {
for(int i = tp - x.FI.SE; i > 0 && dep[sk[i]] >= dep[x.FI.FI]; i -= x.SE.FI)
ans[x.SE.SE] = max(ans[x.SE.SE], a[sk[i]]);
}
qy[u].clear();
for(auto v : G[u])
if(v ^ fa[u])
dfs(v);
-- tp;
} int main() {
int T, cas = 1;
scanf("%d", &T);
while(T --) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i) {
scanf("%d", a + i);
}
for(int u, v, i = 1; i < n; ++ i) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(ans, 0, m * sizeof(int));
label = 0;
dfs1(1, 1); dfs2(1, 1);
for(int i = 0; i < m; ++ i) {
int u, v, k;
scanf("%d%d%d", &u, &v, &k);
if(k >= MAGIC) {
int f = lca(u, v), d = (dep[u] + dep[v] - 2 * dep[f] + 1) % k;
if(u ^ f) qy[u].push_back( { {f, k - 1}, {k, i} } );
if(v ^ f) qy[v].push_back( { {f, d}, {k, i} } );
} else {
qs[k].push_back( { {u, v}, i } );
}
}
for(int i = 1; i < MAGIC; ++ i)
if(qs[i].size())
small_case(i);
tp = 0; dfs(1);
printf("Case #%d:\n", cas ++);
for(int i = 0; i < m; ++ i)
printf("%d\n", ans[i]);
for(int i = 1; i <= n; ++ i)
G[i].clear();
}
return 0;
}

HDU 5840 This world need more Zhu 树链剖分+暴力的更多相关文章

  1. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  2. HDU 3966:Aragorn's Story(树链剖分)

    http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意:有n个点n-1条边,每个点有一个权值,有两种操作:询问一个点上权值是多少和修改u到v这条链上的权值. ...

  3. HDU - 6393 Traffic Network in Numazu(树链剖分+基环树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6393 题意 给n个点和n条边的图,有两种操作,一种修改边权,另一种查询u到v的最短路. 分析 n个点和n条边,实 ...

  4. hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...

  5. Hdu 5052 Yaoge’s maximum profit(树链剖分)

    题目大意: 给出一棵树.每一个点有商店.每一个商店都有一个价格,Yaoge每次从x走到y都能够在一个倒卖商品,从中得取利益.当然,买一顶要在卖之前.可是没次走过一条路,这条路上的全部商品都会添加一个v ...

  6. HDU 5614 Baby Ming and Matrix tree 树链剖分

    题意: 给出一棵树,每个顶点上有个\(2 \times 2\)的矩阵,矩阵有两种操作: 顺时针旋转90°,花费是2 将一种矩阵替换为另一种矩阵,花费是10 树上有一种操作,将一条路经上的所有矩阵都变为 ...

  7. HDU 5893 List wants to travel(树链剖分)

    [题目链接]http://acm.hdu.edu.cn/showproblem.php?pid=5893 [题目大意] 给出一棵树,每条边上都有一个边权,现在有两个操作,操作一要求将x到y路径上所有边 ...

  8. HDU 3966 Aragorn&#39;s Story(树链剖分)

    HDU Aragorn's Story 题目链接 树抛入门裸题,这题是区间改动单点查询,于是套树状数组就OK了 代码: #include <cstdio> #include <cst ...

  9. HDU 5893 List wants to travel(树链剖分+线段树)

    题目链接 HDU5893 $2016$年$ICPC$沈阳网络赛的$B$题.这道题其和 BZOJ2243 基本一样 那道题我也写了题解 点这里 两道题的区别就是$BZOJ$这题是点的权值,这道题是边权. ...

随机推荐

  1. python 通用字典方法

    版本1 方法 # 不传返回所有属性,传入props只返回传入的对应属性 def m_dict(obj, props=[]): result = {} target = obj else props f ...

  2. Java SSM框架之MyBatis3(五)MyBatis之ResultMap详解

    resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中. resultMap包含的元素: <!--column不做限制,可以为任意 ...

  3. 在Emacs中启用Fcitx输入法

    安装fcitx输入法,在 ~/.xinitrc文件中添加如下内容 (我用startx启动图形环境,所以在~/.xinitrc中配置X会话) export LC_CTYPE="zh_CN.UT ...

  4. 使用js获取浏览器地址栏里的参数

    用JS获取地址栏参数的方法(超级简单) 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用又方便!) function GetQueryString(name) { var reg = new ...

  5. Sortable.js

    拖拽的时候主要由这几个事件完成, ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上 ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此 ...

  6. git log查看某一个分支的提交

    如果想查看某一个分支的提交信息:git log 或者是查看分支名:git log $分支名/tag名/远程分支名 查看提交的详情: git log -p

  7. 关于gb2312编码和utf8码的一个问题

    ANSI(注意拼写不是ASCII)并不是“一种”编码,而是“多种”编码的统称.在简体中文Windows上,ANSI指GBK编码:在繁体中文Windows上,ANSI指Big5编码:在英文Windows ...

  8. Hibernate二级缓存(未完待续)

    1.Hibernate的cache介绍: Hibernate实现了良好的Cache机制,可以借助Hibernate内部的Cache迅速提高系统的数据读取性能.Hibernate中的Cache可分为两层 ...

  9. 【干货】操纵时间 感受威胁 MAC time时间戳视角

    来源:Unit 4: Unix/Linux Forensics Analysis 4.1 Unix/Linux Forensics Analysis MAC Times Sleuthkit工具的MAC ...

  10. 【Pyhon】利用BurpSuite到SQLMap批量测试SQL注入

    前言 通过Python脚本把Burp的HTTP请求提取出来交给SQLMap批量测试,提升找大门户网站SQL注入点的效率. 导出Burp的请求包 配置到Burp的代理后浏览门户站点,Burp会将URL纪 ...