zoukankan      html  css  js  c++  java
  • Codeforces Round #633(Div.2) E. Perfect Triples

    E. Perfect Triples

    题目链接

    题目概要:

    有一个无限大的数组(s)。(开始为空)
    每次找到字典序最小的三个数((a,b,c))满足:

    • (aoplus boplus c=0).
    • (a,b,c otin s).
      (t)次询问,每次问数组第(n)项是多少。

    思路:

    打表后我们发现,三元组的第一项始终是 (4^x)后一段连续的数。这样我们尝试在二进制下两位两位的转移
    (也就是四进制,为了使异或看起来方便我们这样描述):
    每两位可以取的数值是(00,01,10,11)
    首先假设已经用完了(1 o 4^n-1)的数,现在考虑(4^n o 4^{n+1}-1)
    要得到 (a<b<c) ,最高的两位只能是(01,10,11),也就是说(a,b,c)最高的两位互不相同。
    现在前两位已经知道了,我们继续往下看。
    我们先把样例给出的几项(二进制)用下表的形式展示:

    (a) (b) (aoplus b)
    (00) (00) (00)
    (01) (10) (11)
    (10) (11) (01)
    (11) (01) (10)

    我们大胆猜测,(以两位为单位)在四进制下,所有的数值都满足以上条件。

    • 两位的情况下((a,b,c))只有(1,2,3),显然满足。
    • 假设(2k)位的情况下(a,b,c)都满足,验证(2k+2)位:
      我们先把这(2k)位左移两位(设其中任意一对数值是(pa,pb,pc),显然(pa oplus pb=pc)),在字典序最小的情况下我们首先考虑(a)
      (00):显然(pa+00,pb+00,pc+00)成立。
      (01):对于(b)(00,01)都不成立((b,c)出现重复),此时应为 (pa+01,pb+10,pc+11)
      ...
      剩下的手推便会发现的确满足上表。

    这样我们只要确定第(n)个数所属的三元组((a,b,c))(a)即可确定这个值。

    代码:

    #include "iostream"
    #include "stdio.h"
    #include "string.h"
    #include "algorithm"
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const int N=1e6+5;
    const ll mod=998244353;
    const double eps=1e-5;
    //const double pi=acos(-1);
    
    #define ls p<<1
    #define rs p<<1|1
    ll f[3][4]={{0,3,1,2},{},{0,2,3,1}};
    void solve(ll x,int y)
    {
        if(y==1)
        {
            printf("%lld
    ",x);
            return;
        }
        ll ans=0,p=1;
        while(x)
        {
            ans=ans+f[y][x%4]*p;
            x>>=2;
            p<<=2;
        }
        printf("%lld
    ",ans);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        cin.tie(0);
        int _;
        ll n;
        cin>>_;
        while(_--)
        {
            cin>>n;
            ll j=1,a;
            while(j<=n) j<<=2;
            j>>=2;
            if(j+2>=n) a=j;
            else a=j+(n-j)/3;
            solve(a,n%3);
        }
        return 0;
    }
    
  • 相关阅读:
    管理者的主要任务是什么?
    管理者的最基本职责是什么?
    管理者的两大职责:“管事”和“理人”
    最近的思考
    刨根问底Objective-C Runtime
    Objective-C 中的类和对象
    ios动态添加属性的几种方法
    多态 oc c++ 与oc category
    利用Objective-C运行时hook函数的三种方法
    Hook技术
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/12693020.html
Copyright © 2011-2022 走看看