2017.10.2 国庆清北 D2T2 树上抢男主

/*
我只看懂了求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 树上抢男主的更多相关文章
- 2017.10.1 国庆清北 D1T1 zhx的字符串题
题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...
- 2017.10.4 国庆清北 D4T2 正方形
题目描述 在一个10000*10000的二维平面上,有n颗糖果. LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果! 事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖 ...
- 2017.10.6 国庆清北 D6T2 同余方程组
题目描述 求关于x 的同余方程组 x%a1 = b1 x%a2 = b2 x%a3 = b3 x%a4 = b4 的大于等于0 的最小整数解. 输入输出格式 输入格式: 一行8 个整数,表示a1; b ...
- 2017.10.6 国庆清北 D6T1 排序
题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. 比如a 序列 ...
- 2017.10.3 国庆清北 D3T3 解迷游戏
题目描述 LYK进了一家古董店,它很想买其中的一幅画.但它带的钱不够买这幅画. 幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它. 老板有一个n*m的矩阵,他想 ...
- 2017.10.3 国庆清北 D3T2 公交车
题目描述 LYK在玩一个游戏. 有k群小怪兽想乘坐公交车.第i群小怪兽想从xi出发乘坐公交车到yi.但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点. LYK想让小怪兽们尽可能的到达自己想 ...
- 2017.10.3 国庆清北 D3T1 括号序列
题目描述 LYK有一个括号序列,但这个序列不一定合法. 一个合法的括号序列如下: ()是合法的括号序列. 若A是合法的括号序列,则(A)是合法的括号序列. 若A和B分别是合法的括号序列,则AB是合法的 ...
- 2017.10.4 国庆清北 D4T1 财富
(其实这题是luogu P1901 发射站 原题,而且数据范围还比luogu小) 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以身高为美的环境,因此在 ...
- 2017.10.7 国庆清北 D7T1 计数
题目描述 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍数. 输入输出格式 输入格式: 输入文件名为count.in. 第一行,包含两个整数:n ...
随机推荐
- mysql sql 分析
一.SQL 执行时间分析通过找到执行时间长的 SQL 语句,可以直观的发现数据层的效率问题. 1.通过 show processlist 来查看系统的执行情况mysql> show proces ...
- SharePoint中用Power shell命令设置文档库列表的权限
首先停止继承权限 $web = Get-PnPweb $spoList= Get-PnPList "Testlist" -Web $web (注释:获取对象)$spoList.Br ...
- js 页面技巧
需要获取页面上固定的某个按钮的属性值.我们需要在页面加载完的第一刻将值存储到定义的变量,防止用户更改页面样式读不出当前元素.如果页面刷新会重置当前属性 <body> <input v ...
- String 字符串的==和eqauls区别
1.对于基本类型来说,==比较的是数据的值,equals方法也是数据的值: 对于引用类型来说,==比较的是引用的地址,equals方法比较的是对象的内容. 2.String是引用类型,用“=”创建字符 ...
- 【转载】C#使用Math.Floor方法来向下取整
在C#的数值运算中,有时候需要对计算结果舍去小数位保留整数位向下取整即可,此时就可使用内置方法Math.Floor来实现向下取整操作,Math.Floor方法将舍去小数部分,保留整数.Math.Flo ...
- Android Jetpack组件
带你领略Android Jetpack组件的魅力 Android新框架jetpack的内容讲解:Room.WorkManager.LifeCycles.LiveData.ViewModel.DataB ...
- Redis数据结构和使用场景,redis内存淘汰策略
什么样的数据适合放入Redis? sql执行耗时特别久,且结果不频繁变动的数据,适合放入Redis. Redis是单线程的,为什么会这么快? 纯内存操作 单线程操作,避免频繁的上下文切换 采用了非阻塞 ...
- Python学习日记(五) 编码基础
初始编码 ASCII最开始为7位,一共128字符.最后确定8位,一共256个字符,最左边的为拓展位,为以后的开发做准备. ASCII码的最左边的一位为0. 基本换算:8位(bit) = 1字节(byt ...
- I、Mac 下的Vue
Mac 下的Vue 1. 安装brew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/i ...
- ARM的Semihosting技术(转)
Semihosting技术将应用程序中的IO请求通过一定的通道传送到主机(host),由主机上的资源响应应用程序的IO请求, 而不是像在主机上执行本地应用程序一样,由应用程序所在的计算机响应应用程序I ...