CF1338C Perfect Triples

Lisa

这是个什么玩意

先打个表

然后发现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;
}
posted @ 2021-09-30 18:13  Simex  阅读(24)  评论(0编辑  收藏  举报