题目链接:
https://codeforces.com/contest/1339/problem/E
思路:
打表找规律,发现将三元组的第一个数转化成二进制之后,由低位到高位,将01变成11,10变成01,11,变成10
即为三元组的第二个数的二进制形式然后再异或求出第三个数。
该图为第16个数到第63个数之间的规律
代码:
#include <bits/stdc++.h> #define Pair pair<int,int> using namespace std; typedef long long ll; const int MAXN=100; const ll INF=1e17; void form()//打表的函数 { /*for(int i=64;i<=127;i++) { for(int j=128;j<=255;j++) { for(int k=128;k<=255;k++) { if((i^j^k)==0&&!visit[i]&&!visit[j]&&!visit[k]) { visit[i]=1,visit[j]=1,visit[k]=1; printf("%d %d %d ",i,j,k); } } } }*/ } ll p[MAXN]={0,1},b[MAXN]; int main() { ios::sync_with_stdio(false); cin.tie(0);ll limit=0; for(int i=2;i<=INF;i++) { p[i]=p[i-1]*4; if(p[i]>INF) { limit=i;break; } } int t;cin>>t; while(t--) { ll n;cin>>n;memset(b,0,sizeof(b)); ll index=upper_bound(p+1,p+1+limit,n)-p-1; ll id=(n-p[index])%3,fir=p[index]+(n-p[index])/3; ll temp=fir,cnt=0; while(temp) { b[cnt++]=temp%2;temp/=2; } for(int i=0;i<cnt;i+=2) { if(b[i]==1&&b[i+1]==0) b[i]=0,b[i+1]=1; else if(b[i]==1&&b[i+1]==1) b[i+1]=0; else if(b[i]==0&&b[i+1]==1) b[i]=1; } ll sec=0,item=1; for(int i=0;i<=cnt;i++) { sec+=b[i]*item;item*=2; } ll third=fir^sec; //cout<<id<<" "<<fir<<" "<<sec<<" "<<third<<endl; switch(id) { case 0:cout<<fir<<endl;break; case 1:cout<<sec<<endl;break; case 2:cout<<third<<endl;break; default:break; } } return 0; }