CF1339E-Perfect Triples (打表找规律)

题目链接:

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\n",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;
}

 

posted @ 2020-04-15 15:15  grass_lin  阅读(179)  评论(0编辑  收藏  举报