社区讨论
关于abc_E
学术版参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lo1ayudm
- 此快照首次捕获于
- 2023/10/22 18:05 2 年前
- 此快照最后确认于
- 2023/11/02 18:23 2 年前
拍了几百组数据,都没有问题,不知道错在哪里。
CPP#include<bits/stdc++.h>
using namespace std;
#define int i128
#define i64 long long
#define ull unsigned long long
#define ldb long double
#define db double
#define i128 __int128
#define up(a,b,c) for(int a=(b);a<=(c);a++)
#define dn(a,b,c) for(int a=(b);a>=(c);a--)
#define pii pair<int,int>
#define pivi pair<int,vector<int> >
#define lc k<<1
#define rc k<<1|1
#define fi first
#define se second
#define endl '\n'
#define i16 short
const int N=2e5+100,M=2e6+100;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const ull uinf=1e18+14;
namespace IO{
inline int read(){
char c=getchar();int x=0,fh=0;
while(c<'0'||c>'9'){fh|=c=='-';c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return fh?-x:x;
}
inline void wt(int x){
if(x<0){x=-x;putchar('-');}
if(x>9)wt(x/10);
putchar((x%10)^48);
}
inline void write(int x,bool op){
wt(x);
putchar(op?'\n':' ');
}
}using namespace IO;
int n,k;
inline int ksm(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int len,dep;
inline int clac(int x,int pos){
if(x==0)return 1;
x--;
int u=pos*2+1;
int l=u,r=u;
if(x>=62)return 0;
up(i,1,x){
l=l*2;
r=r*2+1;
}
if(r<=n)return (r-l+1);
if(l>n)return 0;
return n-l+1;
}
inline int clac2(int x,int pos){
if(x==0)return 1;
x--;
int u=pos<<1;
int l=u,r=u;
if(x>=62)return 0;
up(i,1,x){
l=l*2;
r=r*2+1;
}
if(r<=n)return (r-l+1);
if(l>n)return 0;
return n-l+1;
}
int x;
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;
T=read();
while(T--){
n=read();x=read();k=read();
len=0,dep=0;//len表示这棵树有多少层是满二叉树,dep表示在第几层
up(i,0,63){
if((1ll<<i)-1<n&&(1ll<<(i+1))-1>=n){
len=i;
}
if((1ll<<i)-1<x&&(1ll<<(i+1))-1>=x){
dep=i+1;
}
}
if(k==0){
cout<<1<<endl;
continue;
}
int upp=0,down=0;//upp表示x点上方有多少个节点距离为k,down表示下方有多少个点距离为k
int w=k,pos=x,pre=x;
while(pos!=1){//不停的升到父亲节点,如果该点是右儿子,那么查找左儿子,反之亦然
pos/=2;w--;
if(w<0)break;
if(pre==pos*2)upp+=clac(w,pos);
else if(pre==pos*2+1)upp+=clac2(w,pos);
pre=pos;
}
int l=x,r=x;
if(k>=62){
down=0;
goto F;
}
up(i,1,k){
l=l*2;
r=r*2+1;
}
if(r<=n)down=(r-l+1);
else if(l>n)down=0;
else down=n-l+1;
//cout<<down<<endl;
F:;
//cerr<<upp<<" "<<down<<endl;
write(upp+down,1);
//cout<<upp+down<<endl;
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...