/*
我只看懂了求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. SSH协议介绍

    SSH概念介绍 SSH是一种网络协议,我们常说的 ssh 一般指其实现,即 OpenSSH,在 shell 中,也就是 ssh 命令. Secure Shell(安全外壳协议,简称SSH)是一种加密的 ...

  2. 缓存的设计及PHP实现LFU

    1. 恒定缓存性能有哪些因素? 命中率.缓存更新策略.缓存最大数据量. 命中率:指请求缓存次数和缓存返回正确结果次数的比例.比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率.如果数据频繁更新, ...

  3. sql语句将图片插入image类型的字段中

    update table set photo=(SELECT * FROM OPENROWSET(BULK N'D:\no.png', SINGLE_BLOB) as Photo)    From:h ...

  4. Sqlite in flutter, how database assets work

    First off, you will need to construct a sqlite database from your csv. This can be done in the follo ...

  5. kubernetes第六章--如何访问pod

  6. MySQL Replication--修复从库上单个数据库的数据

    问题描述 由于运维失误,从库未及时设置read_only,导致从库上某库数据被修改,由于整个实例数据量较大,重做成本较高,而该数据库数据较少,因此考虑如何修复该数据库的数据. 操作前提 1.复制使用位 ...

  7. MaxScale ERROR 2006 (HY000): MySQL server has gone away

    Error: MaxScale cannot be run as root.Failed to write child process message!解决办法:# maxscale -f /etc/ ...

  8. ab接口压力测试工具使用

    ab的使用 模拟并发请求100次,总共请求10000次 命令模板: ab -c 100 -n 10000 待测试网站(建议完整路径) 内容解释: Server Software: nginx/1.10 ...

  9. gensim中word2vec和其他一些向量的使用

    直接上代码吧,word2vec # test from gensim.models.word2vec import Word2Vec txt_file = open('data.txt') sente ...

  10. 基于Java+Selenium的WebUI自动化测试框架(十四)-----使用TestNG的Sample

    到目前为止,我们所写的东西,都是集中在如何使用Selenium和Java来定位和读取元素.那么,到底如何具体开展测试,如何实现参数化,如何实现判定呢?下面,我们来看看Java应用程序的测试框架吧. 当 ...