首先答案一定是包含直径某个端点的一个连通块里所有边权值之和,设直径为$AB$,以$A$和$B$分别为根进行处理。

首先按照最长路法则将这棵树进行树链剖分,那么每个叶子的贡献为它与它所在链顶端的点的距离。

将叶子按贡献从大到小排序,并求出$h[x]$表示$x$子树内叶子排名的最小值。

对于询问$(x,k)$,需要取$2k-1$个叶子。

如果$h[x]\leq k$,那么说明前$2k-1$个叶子形成的连通块经过了$x$点,直接返回前$2k-1$个叶子的贡献和即可。

否则对于一个选中的叶子$y$,如果它顶端不是$x$的祖先,那么踢掉$y$的代价为$y$的贡献。

否则踢掉$y$的代价为$y$到$lca(x,y)$的距离。

那么对于最优情况,要么踢掉第$2k-1$大的叶子,要么踢掉第二种情况里深度最大的叶子$y$。找到这个$y$可以通过轻重链剖分+二分查找得到。

总时间复杂度为$O((n+m)\log n)$。

#include<cstdio>
#include<algorithm>
#define N 100010
using namespace std;
int n,m,i,x,y,z,g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,d[N],val[N],A,B;
inline bool cmp(int x,int y){return val[x]>val[y];}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int y){
if(d[x]>=d[z])z=x;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)d[v[i]]=d[x]+w[i],dfs(v[i],x);
}
struct DS{
int s[N],f[N],d[N],son[N],top[N],m,q[N],sum[N],h[N];
int size[N],SON[N],TOP[N],dfn,loc[N],seq[N];
void dfs(int x){
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
s[v[i]]=s[x]+w[i],f[v[i]]=x,dfs(v[i]);
if(d[v[i]]+w[i]>=d[x])d[x]=d[son[x]=v[i]]+w[i];
}
}
void dfs2(int x,int y){
top[x]=y;val[x]=s[x]-s[y];
if(!son[x]){q[++m]=x;return;}
dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]&&v[i]!=son[x])dfs2(v[i],x);
}
void dfs3(int x){
if(!h[x])h[x]=m;
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
dfs3(v[i]),h[x]=min(h[x],h[v[i]]),size[x]+=size[v[i]];
if(size[v[i]]>size[SON[x]])SON[x]=v[i];
}
}
void dfs4(int x,int y){
TOP[x]=y;seq[loc[x]=++dfn]=x;
if(SON[x])dfs4(SON[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]&&v[i]!=SON[x])dfs4(v[i],v[i]);
}
void init(int S){
dfs(S),dfs2(S,S);
sort(q+1,q+m+1,cmp);
for(int i=1;i<=m;i++)h[q[i]]=i,sum[i]=sum[i-1]+val[q[i]];
dfs3(S),dfs4(S,S);
}
inline int ask(int l,int r,int k){
int t,mid;
while(l<=r)if(h[seq[mid=(l+r)>>1]]<=k)l=(t=mid)+1;else r=mid-1;
return seq[t];
}
inline int lca(int x,int k){for(;x;x=f[TOP[x]])if(h[TOP[x]]<=k)return ask(loc[TOP[x]],loc[x],k);}
inline int query(int x,int k){
k=k*2-1;
if(k>=m)return sum[m];
if(h[x]<=k)return sum[k];
int y=lca(x,k);
return sum[k]+s[q[h[x]]]-s[y]-min(s[q[k]]-s[top[q[k]]],s[q[h[y]]]-s[y]);
}
}DA,DB;
int main(){
read(n),read(m);
for(i=1;i<n;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
dfs(1,z=0);A=z;
for(i=1;i<=n;i++)d[i]=0;
dfs(A,z=0);B=z;
DA.init(A),DB.init(B);
while(m--)read(x),read(y),printf("%d\n",max(DA.query(x,y),DB.query(x,y)));
return 0;
}

  

BZOJ3607 : 数据网络的更多相关文章

  1. 转:Android 判断用户2G/3G/4G移动数据网络

    Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...

  2. Android 判断用户2G/3G/4G移动数据网络

    Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...

  3. Python数据网络采集5--处理Javascript和重定向

    Python数据网络采集5--处理Javascript和重定向 到目前为止,我们和网站服务器通信的唯一方式,就是发出HTTP请求获取页面.有些网页,我们不需要单独请求,就可以和网络服务器交互(收发信息 ...

  4. jq easyui数据网络的分页过程

    第一次写技术方面的文章,有点忐忑,总怕自己讲的不对误导别人.但是万事总有个开头,有不足错误之处,请各位读者老爷指出. 言归正传,最近刚进新公司,上头要求我先熟悉熟悉easyui这个组件库.在涉及到da ...

  5. (转)Android 判断用户2G/3G/4G移动数据网络

    在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需(要根据用户当前网络情况来做一些调整的,也可以在 App 的设置模块里,让用户自己选择,在 2G ...

  6. 通行导论-IP数据网络基础(2)

    传输控制协议(TCP) 差错控制:TCP使用差错控制提供可靠性,包括检测受到损伤.丢失.失序的报文段 实现方法:1.16位检验和,2.确认机制:采用确认证实收到的报文段,3.重传(设置一个重传超时RT ...

  7. 通信导论-IP数据网络基础(1)

    TCP/IP封装过程: 端口号:服务器一般都是通过知名端口号(1~1023)来识别应用程序,(TCP)21.23.25,(UDP)53.69.161 TCP报文格式: 字节号:TCP把连接中发送的所有 ...

  8. 通信导论-IP数据网络基础(4)

    IP地址的编址方法--IP地址+掩码地址=网络地址 分类的IP地址 每一类地址都由两个固定长度的字段组成,其中一个字段是网络号 net-id,标志主机或路由器所连接到的网络,另一个字段则是主机号 ho ...

  9. 通信导论-IP数据网络基础(3)

    ICMP(IP辅助协议)--网际控制报文协议 ICMP报文种类:ICMP差错报文(终点不可达.时间超过等5种)和ICMP询问报文(回送请求和回答请求.时间戳请求和回答报文2种) ICMP是一种集差错报 ...

随机推荐

  1. 大数运算(python2)

    偶然又遇到了一道大数题,据说python大数运算好屌,试了一发,果然方便-1 a = int( raw_input() ); //注意这里是按行读入的,即每行只读一个数 b = int( raw_in ...

  2. Hive学习路线图(转)

    Hadoophivehqlroadmap学习路线图   1 Comment Hive学习路线图 Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig ...

  3. iOS,Objective-C,相册功能的实现。

    #import "ViewController.h" #define kuan [UIScreen mainScreen].bounds.size.width #define ga ...

  4. 使用drozer连接时提示:Could not find java. Please ensure that it is installed and on your path

    在安装drozer后使用 drozer.bat console connect命令提示如下错误(实际上我已经安装了jdk并添加了path) 参考上面的链接已经它的提示解决方法如下: 建立名为 .dro ...

  5. Delphi中怎么结束线程(这个线程是定时执行的)(方案二)

    上篇博客中提出了一个问题:怎么结束一个定时循环执行的线程,并给出了一个解决方案,但是又出现了一个问题,详细去参考上一篇博客. 然后出去撒了个尿,突然脑子里出现了一个想法(看来工作和思考久了,出去走走, ...

  6. OCJP(1Z0-851) 模拟题分析(二)over

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  7. java创建线程的几种方式

    1.继承Thread类 /** * @author Ash * @date: 2016年8月6日 下午10:56:45 * @func: 通过继承Thread类来实现多线程 * @email 4086 ...

  8. .NET NLog 详解(五) - Condition Expression

    Sample <!-- during normal execution only log Info messages --> <defaultFilter>level > ...

  9. 【leetcode】plus One

    问题描述: Given a non-negative number represented as an array of digits, plus one to the number. The dig ...

  10. 高质量C++[转]

    高质量C++/C编程指南 文件状态 [  ] 草稿文件 [√] 正式文件 [  ] 更改正式文件 文件标识: 当前版本: 1.0 作    者: 林锐 博士 完成日期: 2001年7月24日 版 本  ...