分析:
第一想法就是把这棵树全部模拟出来,但是比较复杂,就没写出来。
非常巧妙的方法,就是找到这棵树最左边和最右边的位置,然后依次向下寻找,每一层的节点个数就是最右边的-最左边的+1,我们也只需要判断一下最右边是否会大于n就可以了,这就相当于一层一层的计算节点个数,简单多了。
但是,最左边和最右边的位置就要自己推算出来了。这个就自己要好好想想。
代码示例:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll n,m,k;
int main(){
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int t;cin>>t;
while(t--){
cin>>n>>m>>k;
ll l,r;
l=r=k;//真的要脑子啊
ll ans=1;//k节点本身
while(1){//遍历到最后一层的时候结束
// (i-1)*m+2 // 左边
// i*m+1 // 右边
if(r*m+1<=n){// 最右边仍有数据,没到最后一层
l=(l-1)*m+2;//到下一层
r=r*m+1;
ans+=r-l+1;//每一层的的节点个数就是 r-l+1
}else if(r*m+1>n&&((l-1)*m+2)<=n){//说明这个节点有子树,但是不全
l=(l-1)*m+2;
r=n;
ans+=r-l+1;
}else{
break;//表名所有子树节点遍历完毕
}
}
cout<<ans<<"\n";
}
return 0;
}