HRBUST2064-分析极端情况+倍增求树上距离
Posted hans774882968
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HRBUST2064-分析极端情况+倍增求树上距离相关的知识,希望对你有一定的参考价值。
传送门。一道不错的思考题~
建议自己先思考下,看有没有结论~
我们不妨分析下,无法构成三角形的边最多能有多少条。设边从小到大为e[0],e[1],e[2]...
,则要满足e[0]+e[1]<=e[2],e[1]+e[2]<=e[3]...
。最坏情况就是斐波那契数列。而边权只有1e9,因此只需要求出这个范围内的斐波那契数列能容纳几项。
设f[0]=f[1]=1
,则f[51]=32951280099
大于1e9。所以在边数大于60时,直接输出Yes是正确的。边数<=60时,直接暴力即可,相信大家都会写。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)
const int N = 100000 + 5,SZ1 = 20;
int n,m,D;
int dep[N],fa[N][SZ1];int pa[N][2];
vector<pair<int,int> > G[N];
void dbg(){puts("");}
template<typename T, typename... R>void dbg(const T &f, const R &... r) {
cout << f << " ";
dbg(r...);
}
template<typename Type>inline void read(Type &xx){
Type f = 1;char ch;xx = 0;
for(ch = getchar();ch < '0' || ch > '9';ch = getchar()) if(ch == '-') f = -1;
for(;ch >= '0' && ch <= '9';ch = getchar()) xx = xx * 10 + ch - '0';
xx *= f;
}
void dfs(int u = 1,int ufa = 0,int w = 0){
dep[u] = dep[ufa] + 1;fa[u][0] = ufa;
pa[u][0] = ufa;pa[u][1] = w;
rep(i,1,D) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for(auto x: G[u]){
int v = x.first;
if(v == ufa) continue;
dfs(v,u,x.second);
}
}
int LCA(int x,int y){
if(dep[x] < dep[y]) swap(x,y);
for(int d = dep[x] - dep[y],i = 0;d;d >>= 1,++i) if(d & 1) x = fa[x][i];
if(x == y) return x;
dwn(i,D,0) if(fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i];
return fa[x][0];
}
inline int dis(int x,int y,int l){
return dep[x] + dep[y] - (dep[l] << 1);
}
int main(int argc, char** argv) {
while(~scanf("%d",&n)){
D = log(n) / log(2) + 1;
rep(i,1,n) G[i].clear();
re_(i,1,n){
int x,y,w;read(x);read(y);read(w);
G[x].push_back({y,w});G[y].push_back({x,w});
}
dfs();
read(m);
while(m--){
int x,y;read(x);read(y);
int lca = LCA(x,y);
if(dis(x,y,lca) > 60){
puts("Yes");continue;
}
vector<int> edges;
for(;x != lca;x = pa[x][0]) edges.push_back(pa[x][1]);
for(;y != lca;y = pa[y][0]) edges.push_back(pa[y][1]);
sort(edges.begin(),edges.end());
bool fl = false;
re_(i,2,edges.size()) if(edges[i] < edges[i-1] + edges[i-2]){
fl = true;break;
}
puts(fl ? "Yes" : "No");
}
}
return 0;
}
以上是关于HRBUST2064-分析极端情况+倍增求树上距离的主要内容,如果未能解决你的问题,请参考以下文章