/*
我只看懂了求LCA
*/ #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 100005
using namespace std; int n,m,head,tot;
int first[N],fa[N][],deep[N],z[N*],que[N],sum[N*][],fd[N],start[N],endd[N],value[N]; struct edge
{
int u,v,w,next;
}edge[N<<]; inline void add_edge(int u,int v,int w)
{
++head;
edge[head].u=u;
edge[head].v=v;
edge[head].w=w;
edge[head].next=first[u];
first[u]=head;
} inline int get(int p,int d)
{
if(d==-) return p;
int x=;
while(d)
{
if(d&) p=fa[p][x];
d>>=;
x++;
}
return p;
} inline int get_lca(int a,int b)
{
if(deep[a]<deep[b]) swap(a,b);
a=get(a,deep[a]-deep[b]);
int x=;
while(a!=b)
{
if(!x||fa[a][x]!=fa[b][x])
{
a=fa[a][x];
b=fa[b][x];
x++;
}
else x--;
}
return a;
} inline int calc(int a,int b)
{
if(a==fa[b][]) return value[]-value[b];
return value[a]+fd[a];
} inline int calcp(int p,int v)
{
int l=start[p]-,r=endd[p];
while(l+<r)
{
int mid=(l+r)>>;
if(v>z[mid]) l=mid;
else r=mid;
}
return r;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
tot+=w;
add_edge(u,v,w);
add_edge(v,u,w);
}
deep[]=;
int front=,tail=;
que[]=;
while(front<=tail) //预处理每个点倍增值
{
int now=que[front++];
for(int i=first[now];i;i=edge[i].next)
{
int to=edge[i].v;
if(!deep[to])
{
deep[to]=deep[now]+;
fd[to]=edge[i].w;
fa[to][]=now;
int pre=now,x=;
while(fa[pre][x])
{
fa[to][x+]=fa[pre][x];
pre=fa[pre][x];
x++;
}
que[++tail]=to;
}
}
}
int cnt=;
for(int i=n;i;i--)
{
int now=que[i];
start[now]=cnt+;
for(int i=first[now];i;i=edge[i].next)
{
int to=edge[i].v;
if(deep[to]==deep[now]+)
{
z[++cnt]=value[to]+edge[i].w;
value[now]+=value[to]+edge[i].w;
}
}
z[++cnt]=tot-value[now];
endd[now]=cnt;
sort(z+start[now],z+endd[now]+);
sum[endd[now]][]=z[endd[now]];
sum[endd[now]][]=;
for(int i=endd[now]-;i>=start[now];i--)
{
sum[i][]=sum[i+][];
sum[i][]=sum[i+][];
if((i&)==(endd[now]&)) sum[i][]+=z[i];
else sum[i][]+=z[i];
}
cnt++;
}
for(int i=;i<=m;i++)
{
int p1,p2;
scanf("%d%d",&p1,&p2);
int lca=get_lca(p1,p2);
int dis=deep[p1]+deep[p2]-*deep[lca];
int delta=dis/+(dis&);
int px,px1,px2;
if(deep[p1]-deep[lca]<delta) px=get(p2,dis-delta);
else px=get(p1,delta);
if(deep[p1]-deep[lca]<delta-) px1=get(p2,dis-delta+);
else px1=get(p1,delta-);
if(deep[p2]-deep[lca]<dis-delta-) px2=get(p1,delta+);
else px2=get(p2,dis-delta-);
int ans=;
if(p1==px)
{
if(p2==px) ans=sum[start[px]][];
else
{
int v2=calc(px2,px);
int p=calcp(px,v2);
ans=sum[p+][]+sum[start[px]][]-sum[p][];
}
}
else
{
if(p2==px)
{
int v1=calc(px1,px);
int p=calcp(px,v1);
ans=v1+sum[p+][]+sum[start[px]][]-sum[p][];
}
else
{
int v1=calc(px1,px);
int pp1=calcp(px,v1);
int v2=calc(px2,px);
int pp2=calcp(px,v2);
if(pp2==pp1) pp2++;
if(pp1>pp2) swap(pp1,pp2);
ans=v1+sum[pp2+][dis&]+sum[pp1+][-(dis&)]-sum[pp2][-(dis&)]+sum[start[px]][dis&]-sum[pp1][dis&];
}
}
printf("%d\n",ans);
}
return ;
}

2017.10.2 国庆清北 D2T2 树上抢男主的更多相关文章

  1. 2017.10.1 国庆清北 D1T1 zhx的字符串题

    题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...

  2. 2017.10.4 国庆清北 D4T2 正方形

    题目描述 在一个10000*10000的二维平面上,有n颗糖果. LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果! 事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖 ...

  3. 2017.10.6 国庆清北 D6T2 同余方程组

    题目描述 求关于x 的同余方程组 x%a1 = b1 x%a2 = b2 x%a3 = b3 x%a4 = b4 的大于等于0 的最小整数解. 输入输出格式 输入格式: 一行8 个整数,表示a1; b ...

  4. 2017.10.6 国庆清北 D6T1 排序

    题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. 比如a 序列 ...

  5. 2017.10.3 国庆清北 D3T3 解迷游戏

    题目描述 LYK进了一家古董店,它很想买其中的一幅画.但它带的钱不够买这幅画. 幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它. 老板有一个n*m的矩阵,他想 ...

  6. 2017.10.3 国庆清北 D3T2 公交车

    题目描述 LYK在玩一个游戏. 有k群小怪兽想乘坐公交车.第i群小怪兽想从xi出发乘坐公交车到yi.但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点. LYK想让小怪兽们尽可能的到达自己想 ...

  7. 2017.10.3 国庆清北 D3T1 括号序列

    题目描述 LYK有一个括号序列,但这个序列不一定合法. 一个合法的括号序列如下: ()是合法的括号序列. 若A是合法的括号序列,则(A)是合法的括号序列. 若A和B分别是合法的括号序列,则AB是合法的 ...

  8. 2017.10.4 国庆清北 D4T1 财富

    (其实这题是luogu P1901 发射站 原题,而且数据范围还比luogu小) 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以身高为美的环境,因此在 ...

  9. 2017.10.7 国庆清北 D7T1 计数

    题目描述 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍数. 输入输出格式 输入格式: 输入文件名为count.in. 第一行,包含两个整数:n ...

随机推荐

  1. tkinter学习笔记_01

    知识点目录: 1. 文本框 Label var = tk.StringVar() # 文本框 bg 背景颜色 fonnt 字体设置 width 长 height 高 l = tk.Label(root ...

  2. redis订阅与发布系统

    一.概述 1.redis通过publish.subscribe等命令实现了订阅与发布模式. 2.这个功能提供两种信息机制,分别是订阅/发布到频道和订阅/发布到模式. 二.频道的订阅与信息发送 1.re ...

  3. nginx-rtmp之直播视频流的推送

    一.RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写.该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变 ...

  4. Matlab图像处理基础知识

    Matlab图像处理基础知识 Matlab的图片以矩阵的形式存储,矩阵的行列值为图片的行列的色彩值. 1图像表达方式: 像素索引 图像被视为离散单元.如使用I(2,2)可以获取第二行第二列的像素值 空 ...

  5. Window 使用Nginx 部署 Vue 并把nginx设为windows服务开机自动启动

    1.编译打包Vue项目 在终端输入 npm run build 进行打包编译.等待... 打包完成生成dist文件夹,这就是打包完成的文件. 我们先放着,进行下一步. 2下载Nginx 下载地址: h ...

  6. BUAA OO 2019 第三单元作业总结

    目录 总 JML规格化设计 理论基础 工具链 规格验证 验证代码 代码静态检查 自动生成测试样例 生成结果 错误分析 作业设计 第九次作业 架构 代码实现 第十次作业 架构 代码实现 第十一次作业 架 ...

  7. VS2017 配置 boost_1_70

    1. 下载与安装 1.1 安装方法1 (1) 下载 https://www.boost.org/ 或者使用 https://sourceforge.net/projects/boost/files/b ...

  8. PHP 的一款http请求封装类

    <?php namespace hisi; class Http { protected static $userAgent = [ 'Mozilla/5.0 (Windows NT 6.1; ...

  9. 【转载】 C#中通过Where方法查找出所有符合条件的元素集合

    在C#的List集合对象中,FirstOrDefault方法可以用于查找List集合中符合条件的第一个元素,如果需要根据条件查找到List集合中的所有符合条件的元素对象集合,则需要使用到List集合的 ...

  10. js中for循环点击事件(闭包)

    <!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" ...