计蒜客 2019南昌邀请网络赛J Distance on the tree(主席树)题解
题意:给出一棵树,给出每条边的权值,现在给出m个询问,要你每次输出u~v的最短路径中,边权 <= k 的边有几条
思路:当时网络赛的时候没学过主席树,现在补上。先树上建主席树,然后把边权交给子节点,然后数量就变成了 u + v - lca * 2。专题里那道算点权的应该算原题吧。1A = =,强行做模板题提高自信。
代码:
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int M = maxn * 30;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n, m;
int root[maxn], tot;
struct Edge{
int v, next;
ll w;
}edge[maxn << 1];
int head[maxn], tol;
void addEdge(int u, int v, ll w){
edge[tol].v = v;
edge[tol].w = w;
edge[tol].next = head[u];
head[u] = tol++;
}
struct node{
int lson, rson;
int sum;
}T[maxn * 40];
void init(){
memset(T, 0, sizeof(T));
memset(root, 0, sizeof(root));
memset(head, -1, sizeof(head));
tot = tol = 0;
}
vector<int> vv;
int getid(int x){
return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + 1;
}
void update(int l, int r, int &now, int pre, int v, int pos){
T[++tot] = T[pre], T[tot].sum += v, now = tot;
if(l == r) return;
int m = (l + r) >> 1;
if(pos <= m)
update(l, m, T[now].lson, T[pre].lson, v, pos);
else
update(m + 1, r, T[now].rson, T[pre].rson, v, pos);
}
void build(int now, int pre, ll w){
update(1, vv.size(), root[now], root[pre], 1, getid(w));
for(int i = head[now]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v == pre) continue;
build(v, now, edge[i].w);
}
}
int query(int l, int r, int now, int pre, int lca, int k){
if(l == r){
if(k >= l) return T[now].sum + T[pre].sum - T[lca].sum * 2;
return 0;
}
if(r <= k) return T[now].sum + T[pre].sum - T[lca].sum * 2;
int m = (l + r) >> 1;
int sum = 0;
if(k <= m)
return query(l, m, T[now].lson, T[pre].lson, T[lca].lson, k);
else{
sum = query(m + 1, r, T[now].rson, T[pre].rson, T[lca].rson, k);
return sum + T[T[now].lson].sum + T[T[pre].lson].sum - T[T[lca].lson].sum * 2;
}
} //lca
int fa[maxn][20];
int dep[maxn];
void lca_dfs(int u, int pre, int d){
dep[u] = d;
fa[u][0] = pre;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v != pre)
lca_dfs(v, u, d + 1);
}
}
void lca_update(){
for(int i = 1; (1 << i) <= n; i++){
for(int u = 1; u <= n; u++){
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
}
}
int lca_query(int u, int v){
if(dep[u] < dep[v]) swap(u, v);
int d = dep[u] - dep[v];
for(int i = 0; (1 << i) <= d; i++){
if(d & (1 << i)){
u = fa[u][i];
}
}
if(u != v){
for(int i = (int)log2(n); i >= 0; i--){
if(fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
}
u = fa[u][0];
}
return u;
}
int u1[maxn], v1[maxn];
ll k1[maxn];
int main(){
init();
vv.clear();
scanf("%d%d", &n, &m);
vv.push_back(0);
for(int i = 1; i <= n - 1; i++){
int u, v;
ll w;
scanf("%d%d%lld", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
vv.push_back(w);
}
for(int i = 1; i <= m; i++){
scanf("%d%d%lld", &u1[i], &v1[i], &k1[i]);
vv.push_back(k1[i]);
}
sort(vv.begin(), vv.end());
vv.erase(unique(vv.begin(), vv.end()), vv.end());
lca_dfs(1, 0, 1);
lca_update();
build(1, 0, 0);
for(int i = 1; i <= m; i++){
int lca = lca_query(u1[i], v1[i]);
printf("%d\n", query(1, vv.size(), root[u1[i]], root[v1[i]], root[lca], getid(k1[i])));
}
return 0;
}
计蒜客 2019南昌邀请网络赛J Distance on the tree(主席树)题解的更多相关文章
- 2019南昌邀请赛网络赛:J distance on the tree
1000ms 262144K DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(N ...
- 2019南昌网络赛 J Distance on the tree 主席树+lca
题意 给一颗树,每条边有边权,每次询问\(u\)到\(v\)的路径中有多少边的边权小于等于\(k\) 分析 在树的每个点上建\(1\)到\(i\)的权值线段树,查询的时候同时跑\(u,v,lca ...
- 2019南昌邀请赛网络预选赛 J.Distance on the tree(树链剖分)
传送门 题意: 给出一棵树,每条边都有权值: 给出 m 次询问,每次询问有三个参数 u,v,w ,求节点 u 与节点 v 之间权值 ≤ w 的路径个数: 题解: 昨天再打比赛的时候,中途,凯少和我说, ...
- 南昌网络赛J. Distance on the tree 树链剖分+主席树
Distance on the tree 题目链接 https://nanti.jisuanke.com/t/38229 Describe DSM(Data Structure Master) onc ...
- 南昌网络赛J. Distance on the tree 树链剖分
Distance on the tree 题目链接 https://nanti.jisuanke.com/t/38229 Describe DSM(Data Structure Master) onc ...
- 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(一)
D题:马的管辖 二进制枚举方案.判断该方案是否全部能被覆盖,将最优方案存下来并进行剪枝. #include<iostream> #include<cstring> #inclu ...
- 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(三)一笔画
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> us ...
- 计蒜客 2019 蓝桥杯省赛 B 组模拟赛(三)数字拆分
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> us ...
- 蒜厂年会|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
样例输入: 3 1 -2 1 样例输出: 2 方法一: 将环形数组拆分成为普通数组,(通过搬运复制数据到尾部),再求前缀和,找出最大前缀和.因为枚举了每一个起点,所以最大连续和也一定出现在前缀和中.. ...
随机推荐
- uni-app开发经验分享五: 解决三端页面兼容问题的方法
在做uni-app开发的过程中,我们最头疼可能不是开发的过程中的逻辑,而是最后要做的三端兼容测试和修改,在我开发的项目中,这一步都是最头疼和令人头秃的过程,这里总结一些个人开发遇到的问题,希望对大家有 ...
- Devexpress DockManager多页面浮动窗口会关闭所有页面的问题
注册 DockManager 的 ClosingPanel 事件 private void DockManager1_ClosingPanel(object sender, DockPanelCanc ...
- Azure DevOps Pipelines执行RobotFramework自动化代码
一.Azure DevOps介绍 1.什么是 Azure DevOps? Azure DevOps其实是VSTS(Visual Studio Team Service)更名后的名字.而VSTS是TFS ...
- Avoid catching exceptions inside atomic! You may need to manually revert model state when rolling back a transaction. 避免异常程序不抛错误 回滚 导致 自增id不连续。
https://docs.djangoproject.com/en/3.0/topics/db/transactions/ You may need to manually revert model ...
- (Sql Server)SQL FOR XML
摘要:sql中的for xml语法为表转化为xml提供了很好的支持,当然使用同样的程序语言也能够达到同样的效果,但是有了for xml将使得这一切更加的方便. 主要内容: Select 的查询结果会作 ...
- 签名 sign key 纸质邮件 历史 RSA诞生历史
API接口签名校验,如何安全保存appsecret? - 知乎 https://www.zhihu.com/question/40855191 要保证一般的客户端-服务器通信安全,可以使用3个密钥. ...
- scrapy爬虫 简单入门
1. 使用cmd+R命令进入命令行窗口,并进入你需要创建项目的目录 cd 项目地址 2. 创建项目 scrapy startproject <项目名> cd <项目名> 例如 ...
- mysql8.0.19忘记密码
1.管理员打开cmd窗口 2.输入net stop mysql,停止mysql服务 3.开启跳过验证密码的mysql服务 用记事本打开 输入skip-grant-tables ,保存 4.管理员打开新 ...
- (十二)整合 Shiro 框架,实现用户权限管理
整合 Shiro 框架,实现用户权限管理 1.Shiro简介 1.1 基础概念 1.2 核心角色 1.3 核心理念 2.SpringBoot整合Shiro 2.1 核心依赖 2.2 Shiro核心配置 ...
- Display属性学习总结
HTMl元素根据表现形式,常见的可以分为两类. (1)块元素(block) (2)行内元素(inline). 当然,除了以上两种元素类型外,还有inline-block.table-cell等元素类型 ...