zoukankan      html  css  js  c++  java
  • #4508. Triples I

    题目描述

    已知 $a$,你可以选 $m$ 个数,满足每个数均为 $3$ 的倍数,且 $m$ 个数的或为 $a$.

    试最小化 $m$.

    数据范围

    对 $100\%$ 的数据,$Tle 10^5$,$ale 10^{18}$.

    题解

    挺水的一题

    如果 $a$ 是 $3$ 的倍数,则直接用 $a$ 即可

    否则考虑能否用两个 $3$ 的倍数的数或起来为 $a$

    把 $a$ 拆位,显然 $2^i\%3=1/2$ ,所以把 $\%3$为 $1$ 的和 $\%3$ 为 $2$ 的位置分开,然后多的那一边拿出两个数相加,这样就可以放在另一边了,重复上述操作直到两边的差不超过 $1$ 即可

    代码

    #include <bits/stdc++.h>
    #define _(d) while(d(isdigit(c=getchar())))
    typedef long long LL;using std::swap;
    LL R(){char c;_(!);LL x=c^48;_()x=(x<<3)+(x<<1)+(c^48);return x;}
    int T,t[2],m,u,v;LL a,p[2][65],x,y,j;
    int main(){
        for (scanf("%d",&T);T--;){
            a=R();
            if (a%3==0){printf("1 %lld
    ",a);continue;}
            j=1;t[0]=t[1]=0;
            for (int i=0;j<=a;i++,j<<=1)
                if (a&j) p[i&1][++t[i&1]]=j;
            u=0;v=1;if (t[0]>t[1]) swap(u,v);
            while(t[v]-t[u]>1)
                p[u][++t[u]]=p[v][t[v]]|p[v][t[v]-1],t[v]-=2;
            u=0;v=1;if (t[0]>t[1]) swap(u,v);
            x=0,y=0;for (int i=1;i<=t[u];i++)
                x|=(p[u][i]|p[v][i]),y|=(p[u][i]|p[v][i+1]);
            printf("2 %lld %lld
    ",x,y);
        }
        return 0;
    }
  • 相关阅读:
    activiti--操作例子
    activiti--服务表
    spring--加载资源文件
    Day17
    Day15
    Day14
    Day13
    Day12
    Day16
    Day11
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/11370163.html
Copyright © 2011-2022 走看看