COJ966 WZJ的数据结构(负三十四)
| WZJ的数据结构(负三十四) |
| 难度级别:C; 运行时间限制:20000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
|
试题描述
|
|
给一棵n个节点的树,请对于形如"u r"的Q个询问, 回答以 u 节点为中心,半径 r 以内的节点中,权值最大的节点的编号是多少。如果有多个节点,返回编号最小的。
|
|
输入
|
|
共有一组测试数据。
第一行包含一个整数 n (1 ≤ n ≤ 10^5),表示节点总数。 接下来的一行,包含 n 个数字,表示每个节点的权值 vi (1 ≤ vi ≤ 10^6)。 接下来的 n-1 行,每行三个整数 (ai, bi, wi),表示一条连接 ai, bi 节点的边,边长为 wi(1 ≤ ai, bi ≤ n, 1 ≤ wi ≤ 3)。 接下来的一行包含一个整数 q,表示询问总数(1 ≤ q ≤ 10^5)。 接下来 q 行,每行包含两个整数 u, r(1 ≤ u ≤ n, 0 ≤ r ≤300),表示询问以 u 节点为中心,半径 r 以内的节点中,权值最大的节点的编号是多少。如果有多解返回编号最小的。 |
|
输出
|
|
对于每组询问,输出一行表示对应答案。
|
|
输入示例
|
|
7
1 2 3 4 5 6 7 1 2 1 2 3 1 2 4 1 1 5 1 5 6 1 5 7 1 4 1 1 1 2 2 1 2 2 |
|
输出示例
|
|
5
7 4 5 |
|
其他说明
|
|
样例很邪恶哦。
|
考虑用点分治离线来解决这道题,那么问题转换成怎么解决过重心x的询问Max(val[y]|depx+depy<=r)。
我们可以用往常的做法,维护dep、val同时递增的决策序列,这个可以用平衡树来做,然后正反扫一遍。
但其实没有必要,注意x、y在同一棵子树并不会影响答案(想一想,为什么),所以只需离线构出决策序列然后二分就行了。
#include<cstdio>
#include<cctype>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
int first[maxn],next[maxn<<],to[maxn<<],dis[maxn<<],e;
void AddEdge(int w,int v,int u) {
to[++e]=v;dis[e]=w;next[e]=first[u];first[u]=e;
to[++e]=u;dis[e]=w;next[e]=first[v];first[v]=e;
}
int n,q,val[maxn],ans[maxn];
int better(int x,int y) {
if(val[x]<val[y]||(val[x]==val[y]&&x>y)) return ;
return ;
}
void relax(int& x,int y) {if(better(y,x)) x=y;}
struct Query {
int x,r,id,next;
}Q[maxn];
int first2[maxn],cnt;
void AddQuery(int id,int r,int x) {
Q[++cnt]=(Query){x,r,id,first2[x]};first2[x]=cnt;
}
int vis[maxn],f[maxn],s[maxn],size,root;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(to[i]!=fa&&!vis[to[i]]) {
getroot(to[i],x);
s[x]+=s[to[i]];maxs=max(maxs,s[to[i]]);
}
f[x]=max(maxs,size-s[x]);
if(f[root]>f[x]) root=x;
}
int tot,num[maxn],dep[maxn],id[maxn],A[maxn],B[maxn];
void dfs(int x,int fa,int D) {
num[++tot]=x;dep[tot]=D;
ren if(to[i]!=fa&&!vis[to[i]]) dfs(to[i],x,D+dis[i]);
}
int cmp(int x,int y) {return dep[x]<dep[y]||(dep[x]==dep[y]&&val[num[x]]>val[num[y]]);}
void solve(int x) {
vis[x]=;tot=;dfs(x,,);
rep(i,,tot) id[i]=i;
sort(id+,id+tot+,cmp);
int tmp=tot;tot=;
rep(i,,tmp) if(better(num[id[i]],A[tot])) A[++tot]=num[id[i]],B[tot]=dep[id[i]];
rep(i,,tmp) for(int j=first2[num[i]];j;j=Q[j].next) {
int l=,r=tot+;
while(l+<r) {
int mid=l+r>>;
if(B[mid]<=Q[j].r-dep[i]) l=mid;
else r=mid;
}
if(B[l]<=Q[j].r-dep[i]) relax(ans[Q[j].id],A[l]);
}
ren if(!vis[to[i]]) {
size=f[]=s[to[i]];getroot(to[i],root=);
solve(root);
}
}
int main() {
n=read();
rep(i,,n) val[i]=read();
rep(i,,n) AddEdge(read(),read(),read());
q=read();
rep(i,,q) AddQuery(i,read(),read());
size=f[]=n;getroot(,);
solve(root);
rep(i,,q) printf("%d\n",ans[i]);
return ;
}
COJ966 WZJ的数据结构(负三十四)的更多相关文章
- 数据结构(三十四)最短路径(Dijkstra、Floyd)
一.最短路径的定义 在网图和非网图中,最短路径的含义是不同的.由于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径:而对于网图来说,最短路径是指两顶点之间经过的边上权值之 ...
- COJ970 WZJ的数据结构(负三十)
WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...
- COJ968 WZJ的数据结构(负三十二)
WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...
- COJ 0970 WZJ的数据结构(负三十)树分治
WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...
- [COJ0968]WZJ的数据结构(负三十二)
[COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...
- [COJ0970]WZJ的数据结构(负三十)
[COJ0970]WZJ的数据结构(负三十) 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为 ...
- 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习
孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...
- NeHe OpenGL教程 第三十四课:地形
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- COJ 1003 WZJ的数据结构(三)ST表
WZJ的数据结构(三) 难度级别:B: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的 ...
随机推荐
- BZOJ1050 [HAOI2006]旅行
其实这道题根本不用最短路算法... 我们可以就把边从小到大排序,那么只需要枚举大小两个端点,把中间的边都加进去判断联通性即可. 判断联通性显然用的是并查集. #include <cstdio&g ...
- ssh连接慢的问题的解决?
<1>群中同学遇到的问题,我之前在uuwatch也遇到了同样的问题? 问个问题师兄们 突然之间 公司服务器连接很慢 连一个shell需要10几秒钟 服务器就在公司全是内网服务器, 我也不知 ...
- linux安装setup工具
如果你的Linux系统是最小化安装的,可能会没有setup命令工具,环境是centos 5.8 安装setup命令工具的步骤. 安装setuptool #yum install setuptool 系 ...
- MVC 修饰标签
MVC中的修饰标签有很多用途.它以修饰标签形式应用在控制器或控制器中的动作上. 最先想到的就是AcceptVerbs标签,在创建的时候,如果导航到创建视图,但不创建,则: public ActionR ...
- WPF 将PPT,Word转成图片
在Office下,PowerPoint可以直接把每张幻灯片转成图片,而Word不能直接保存图片.所以只能通过先转换成xps文件,然后再转成图片. 一.PPT 保存为图片 /// <summary ...
- Java for LeetCode 165 Compare Version Numbers
Compare two version numbers version1 and version2.If version1 > version2 return 1, if version1 &l ...
- Greedy:Fence Repair(POJ 3252)
Fence Repair 问题大意:农夫约翰为了修理栅栏,要将一块很长的木块切割成N块,准备切成的木板的长度为L1,L2...LN,未切割前的木板的长度恰好为切割后木板的长度的总和,每次切断木板的时候 ...
- codeforces B. The Fibonacci Segment 解题报告
题目链接:http://codeforces.com/problemset/problem/365/B 题目意思:简单来说,就是要找出最长的斐波纳契长度. 解决的方法不难,但是要注意更新左区间和右区间 ...
- OC内存管理(MRC)
首先说明一下几块存储区域: 栈区(局部变量.函数参数值) 堆区(对象.手动申请/释放内存) BSS区(未初始化的全局变量.未初始化的静态数据) 常量区(字符串常量以及初始化后的全局变量.初始化后的静态 ...
- C++多线程下的单例模式
一.懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例. 需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread s ...