CF1338C Perfect Triples
这是个什么玩意
先打个表
然后发现a的取值似乎非常有规律
a的一些段落是连续的,然后这些连续的a对于每一块
a,b,c的值是从\(2^{2n-2}-2^{2n}-1\)
且对于b,如果我们把b在同一块里的值分成四部分的话,会发现首项大小是固定的,这四块的大小关系是固定的,这四块的取值范围是固定的,并且可以递归下去
c也可以
这样递归就可以了
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll t,n;
ll calc2(ll x,ll y){
if(x==1) {
return 1;
}else {
ll t=x/4;
if(y<=t) {
return calc2(t,y);
}else if(y<=2*t) {
return calc2(t,y-t)+2*t;
} else{
if(y<=3*t) {
return calc2(t,y-2*t)+3*t;
}else {
return calc2(t,y-3*t)+t;
}
}
}
}
ll calc3(ll x,ll y){
if(x==1) {
return 1;
}else {
ll t=x/4;
if(y<=t) {
return calc3(t,y);
}else if(y<=2*t) {
return calc3(t,y-t)+3*t;
} else{
if(y<=3*t) {
return calc3(t,y-2*t)+t;
}else {
return calc3(t,y-3*t)+2*t;
}
}
}
}
ll calc(ll n){
ll tmp=n%3;
n=(n+2)/3;
ll pos=0;
ll cnt=0;
while(pos+(1ll<<cnt)<n){
pos+=(1ll<<cnt);
cnt+=2;
}
ll res=3*pos;
if(tmp==1){
return res+(n-pos);
}else if(tmp==2){
return res+(1ll<<cnt)+calc2(1ll<<cnt,n-pos);
}else{
return res+(1ll<<(cnt+1))+calc3(1ll<<cnt,n-pos);
}
}
int main(){
scanf("%lld",&t);
for(int i=1;i<=t;++i){
scanf("%lld",&n);
printf("%lld\n",calc(n));
}
return 0;
}