首页 > 其他分享 >CF1338C Perfect Triples 题解

CF1338C Perfect Triples 题解

时间:2024-02-07 10:14:38浏览次数:43  
标签:Perfect 第一个 int 题解 ce 三元组 CF1338C else lld

解题思路

没什么好说的,就是打表找规律……

表在这里

不难发现,三元组中第一个数的最后两位按照 \(00\to 01\to 10\to 11\) 的顺序变化,其他位也一样,同样,第二个数和第三个数中每两位分别按照 \(00\to 10\to 11\to 01\) 和 \(00 \to 11\to 01\to 10\) 的顺序变化,且与第一个数对应变化。那么只要我们第一个数确定了,第二个和第三个数也就确定了,因此,我们的问题变为了如何快速确定第一个数。

观察发现,当 \(n=4^k\) 且 \(k\in \mathbb Z\) 时,三元组第一个数为 \(n\)。并且可以看出,在第一个数为 \(4^k\sim 2^{2\times k}-1\) 的连续若干个三元组中,第一个数是连续的,即分别为 \(4^k,\dots,2^{2\times k}-1\)。由此,我们可以找到第一个小于等于 \(n\) 的 \(x\) 使得 \(x=4^k\) 且 \(k\in\mathbb Z\),那么 \(n\) 所在三元组的第一个数即为 \(\displaystyle 2^k+\frac{n-2^k}{3}\)。

综上,本题步骤为:

  • 找到第 \(n\) 个数所在三元组的第一个数;
  • 令第一个数为 \(m\),我们将 \(m\) 转化为二进制,并将其位数补为偶数;
  • 根据 \(m\) 从最高位开始,每两位为一组,计算出对应的第 \(2\)、\(3\) 个数的这两位;
  • 将第 \(2\)、\(3\) 个数转化位十进制下整数;
  • 判断 \(M=n\bmod 3\) 并输出,若 \(M=1\),输出第一个数,若 \(m=2\),输出第二个数,否则输出第三个数。

AC 代码

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include <string.h>
#define int long long
#define N 100
int n,m;char a[N],b[N],c[N];
inline int GetStr(int x,char *s){
    int ce=0;while(x){
        s[++ce]='0'+(x&1);
        x>>=1;
    }return ce&1?ce+1:ce;
}
inline void GetNum(int &x,char *s,int len){
    x=0;for(register int i=len;i>=1;--i)
        x=(x<<1ll)+(s[i]-'0');
}
inline void work(){
    scanf("%lld",&n);int lin;
    for(register int i=60ll;i>=0ll;--i)
        if((n>>i)&1ll){
            m=i&1ll?i-1ll:i;
            lin=m;break;
        }
    int sub=(1ll<<m),res=(n-sub)/3ll;
    m=sub+res;int _1=m,_2,_3;
    for(register int i=1;i<=80;++i)
        a[i]='0';int ce=GetStr(m,a);
    for(register int i=ce;i>=1;i-=2){
        if(a[i]=='0'&&a[i-1]=='0'){
            b[i]='0',b[i-1]='0';
            c[i]='0',c[i-1]='0';
        }else if(a[i]=='0'&&a[i-1]=='1'){
            b[i]='1',b[i-1]='0';
            c[i]='1',c[i-1]='1';
        }else if(a[i]=='1'&&a[i-1]=='0'){
            b[i]='1',b[i-1]='1';
            c[i]='0',c[i-1]='1';
        }else if(a[i]=='1'&&a[i-1]=='1'){
            b[i]='0',b[i-1]='1';
            c[i]='1',c[i-1]='0';
        }
    }GetNum(_2,b,ce),GetNum(_3,c,ce);
    if(n%3==0) printf("%lld\n",_3);
    else if(n%3==1) printf("%lld\n",_1);
    else printf("%lld\n",_2);
}
signed main(){
    int T;scanf("%lld",&T);
    while(T--) work();
    system("pause");
}

标签:Perfect,第一个,int,题解,ce,三元组,CF1338C,else,lld
From: https://www.cnblogs.com/UncleSamDied6/p/18010666

相关文章

  • CF1379C Choosing flowers 题解
    解题思路不是那么显然的,当只选一种\(b_i\)或全选\(a_i\)时最优。那么我们可以先对\(a_i\)从大到小排序,枚举每一个\(b_i\),然后二分找到第一个大于等于\(b_i\)的\(a_j\),判断\(a_1\sima_j\)中是否包含\(a_i\),如果包含,当前的答案为\(\displaystyle\left(\sum_{k=1}^{......
  • CF1385F Removing Leaves 题解
    解题思路简单贪心,优先选择叶子节点最多的,这样能够保证一定能把所有能删的都删了。因为要建一个可删除的图,所以我们可以使用set来存边,不然就需要维护一堆东西……那么我们肯定是从有叶子节点的点向父亲更新的,那么我们每次选择叶子节点最多的点,然后删除\(k\)个叶子,判断一下删......
  • CF1415E New Game Plus! 题解
    解题思路简单贪心题,我们可以把整个序列看作\(k+1\)个可重集,首先可以得到一个显然的结论:较大的数一定比较小的数先放入一个集合中。同样,由于每一轮\(ans\getsans+\maxsum_i\),其中\(sum_i\)表示第\(i\)个集合的元素和,那么,我们一定会将当前的元素放入当前和最大的哪个集合......
  • CF1416B Make Them Equal 题解
    解题思路观察可以发现,每次操作后序列元素之和不变,那么我们可以将每一次操作看作是\(a_i\)向\(a_j\)移动了\(i\timesx\)。由此可得,若序列和\(sum\bmodn\not=0\),那么一定无解,否则一定存在一个合法的操作方案。因为每次移动时移动的数应为\(i\)的倍数,所以\(a_1\)可以向......
  • CF1446C Xor Tree 题解
    解题思路与其考虑删除哪些点,不如考虑保留哪些点。考虑到和异或有关,那么我们可以把这些数倒序插入trie树中,然后我们就可以在trie树上跑一个简单的dp:若当前节点为叶子节点,那么保留,返回\(1\);若当前节点在链上,那么直接继承儿子节点;若当前节点有两个儿子,那么更新为较大儿子......
  • CF1922E Increasing Subsequences 题解
    解题思路因为可以有空集,那么我们首先构造第一段最长的连续上升的序列,那么这段序列中共有\(2^{\mids\mid}\)个上升子序列。接下来我们考虑补全剩余的,我们不妨将剩余的部分全部设为连续不增序列,那么设当前位置在第一段中有\(k\)个小于它的,那么添加这个数后可以增加\(2^{k-1}......
  • CF1413C Perform Easily 题解
    解题思路其实是很简单的一道题,考虑计算出所有\(b_i\)在减去每一个\(a_j\)后所有可能的值,将这个值按照从小到大的顺序排序,那么我们可以考虑固定最小值,查找最大值,这个时候从最小值到最大值的区间内应该每一种\(b_i\)都出现了一次。那么,我们可以使用一个桶或者map搭配双指针......
  • 洛谷P10135 暨 USACOJan2024S T2 题解
    题意简述给点一棵有\(n\)个节点的树,在每个时间点都会在某个节点出现一瓶药水,记\(p_i\)为第\(i\)个时间点出现药水的节点,定义一次遍历为从\(1\)号节点走到任意节点,要求在遍历次数最少的情况下拾取最多数量的药水。思维路径首先我们要探讨遍历次数最少的状态是怎样的。由......
  • CF1922B Forming Triangles 题解
    解题思路显然,有以下两种选择的方法:所有边一样长;两条一样长的边,第三条边小于这两条边。然后组合数计算即可。AC代码#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<vector>#definelllonglong#defineN300005intn,a[N];inlinellC3(llx){......
  • CF1922C Closest Cities 题解
    解题思路贪心,能走距离最短的城市就一定走。分别考虑\(x>y\)和\(x<y\)的情况,两种情况分别是从后向前转移和从前往后转移,分别预处理一个前缀和和后缀和即可。AC代码#include<stdio.h>#include<stdlib.h>#include<valarray>#defineN100005#definelllonglongintn......