T1:二叉树
链接:二叉树_牛客题霸_牛客网 (nowcoder.com)s
题意:给你一颗二叉树,求俩个点的最近公共祖先(LCA)
因为比较特殊,树是一颗二叉树,二叉树的编号很特殊,学过线段树的都知道,假设当前点是x,那俩个儿子的编号就是2*x和2*x+1,父节点的编号是x/2;
所以求LCA就只要让一个点往父节点跳(每次选编号最大的点跳)
时间复杂度:O(logN)
#include<iostream>
using namespace std;
int a,b;
int main()
{
while(cin>>a>>b){
while(a!=b){
if(a>b)a/=2;
else b/=2;
}
cout<<a<<endl;
}
return 0;
}
如果题目不是二叉树呢,并且编号不是这么有规律,如下图
这时阁下应当如何应对呢?
hhh,我选择掏出打ACM时候用的LCA板子
void dfs(int u, int fa)
{
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa)continue;
dis[j] = dis[u] + 1;
f[j][0] = u;
for (int k = 1; (1 << k) <= dis[j]; k++) {
f[j][k] = f[f[j][k - 1]][k - 1];
}
dfs(j, u);
}
}
int lca(int a, int b)
{
if (dis[a] < dis[b])swap(a, b);
int d = dis[a] - dis[b];
for (int i = 0; d; i++) {
if (d & 1)a = f[a][i];
d /= 2;
}
if (a == b)return a;
for (int i = 21; i >= 0; i--) {
if (f[a][i] != f[b][i]) {
a = f[a][i];
b = f[b][i];
}
}
return f[a][0];
}
T2:求最大连续bit数
链接:求最大连续bit数_牛客题霸_牛客网 (nowcoder.com)
描述
求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
数据范围:1≤n≤500000
进阶:时间复杂度:O(logn) ,空间复杂度:O(1)
#include<iostream>
using namespace std;
int n;
int main()
{
cin>>n;
int ans=0;
int cnt=0;
while(n){
int k=n%2;
if(k==1)cnt++;
else cnt=0;
ans=max(cnt,ans);
n/=2;
}
cout<<ans<<endl;
return 0;
}
思想很简单, 取出二进制的每一位,判断是1还是0,是1的话个数+1,否则变为0。然后与ans答案取最大值