Codeforces Round #633 (Div. 2) E. Perfect Triples (打表找規律)

E. Perfect Triples

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Consider the infinite sequence ss of positive integers, created by repeating the following steps:

  1. Find the lexicographically smallest triple of positive integers (a,b,c)(a,b,c) such that
    • a⊕b⊕c=0a⊕b⊕c=0, where ⊕⊕ denotes the bitwise XOR operation.
    • aa, bb, cc are not in ss.
    Here triple of integers (a1,b1,c1)(a1,b1,c1) is considered to be lexicographically smaller than triple (a2,b2,c2)(a2,b2,c2) if sequence [a1,b1,c1][a1,b1,c1] is lexicographically smaller than sequence [a2,b2,c2][a2,b2,c2].
  2. Append aa, bb, cc to ss in this order.
  3. Go back to the first step.

You have integer nn. Find the nn-th element of ss.

You have to answer tt independent test cases.

A sequence aa is lexicographically smaller than a sequence bb if in the first position where aa and bb differ, the sequence aa has a smaller element than the corresponding element in bb.

Input

The first line contains a single integer tt (1≤t≤1051≤t≤105) — the number of test cases.

Each of the next tt lines contains a single integer nn (1≤n≤10161≤n≤1016) — the position of the element you want to know.

Output

In each of the tt lines, output the answer to the corresponding test case.

Example

input

Copy

9
1
2
3
4
5
6
7
8
9

output

Copy

1
2
3
4
8
12
5
10
15

Note

The first elements of ss are 1,2,3,4,8,12,5,10,15,…1,2,3,4,8,12,5,10,15,…

題意:按照字典序,將三元組(x,y,z)依次排序(其中x^y^z==0,x<y<z,已經出現過的數不能再次出現),再依次標號,問你第n(n<=1e16)個數是多少

比如前幾個三元組爲

1 2 3

4 8 12

5 10 15

...

思路:其實打表出來明顯是有規律的,但是不知道咋寫。賽後看大佬們打出來了四進制的表,規律就很明顯了(啊啊啊我怎麼沒想到)

四進制下:
//001 002 003
//1行  第一段 
//010 020 030
//011 022 033
//012 023 031
//013 021 032
//4行  第二段 
//100 200 300
//101 202 303
//102 203 301
//103 201 302
//110 220 330
//111 222 333
//112 223 331
//113 221 332
//120 230 330
//121
//……
//16行   第三段 

很明顯三個數作爲數列中的一項,每一段的第一個數以及段長都是公比爲4的等比數列,然後再根據是三元組中哪一個數

①n%3==1,那麼就是每三個數裏面的第一個數,求一下每一段的第一項第一個數以及段內第幾行加一下就行了

②n%3==2,可以看到在第二列中,減去該段的第一個數*2,每一位四進制都以0 2 3 1循環,加一下就行了

③n%3==0,可以看到在第三列中,減去該段的第一個數*3,每一位四進制都以0 3 1 2循環,加一下就行了

代碼:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=400010;
const ll mo=998244353;
ll n,m,k;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%lld",&n);
        ll p=1,m=n,sum=4;
        while(m>(sum-1)){
            sum<<=2;
        }
        sum>>=2;m=n-(sum-1);
        ll res=(m-1)/3;
        if(n%3==1) printf("%lld\n",sum+res);
        else if(n%3==2){
            ll ans=sum<<1;
            ll c=1;
            while(res){
                if(res%4==1) ans+=2*c;
                else if(res%4==2) ans+=3*c;
                else if(res%4==3) ans+=c;
                res>>=2;
                c<<=2;
            }
            printf("%lld\n",ans);
        }
        else if(n%3==0){
            ll ans=sum*3;
            ll c=1;
            while(res){
                if(res%4==1) ans+=3*c;
                else if(res%4==2) ans+=c;
                else if(res%4==3) ans+=2*c;
                res>>=2;
                c<<=2;
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章