Good Numbers (hard version)-3的幂次方不重复

The only difference between easy and hard versions is the maximum value of nn.

You are given a positive integer number nn. You really love good numbers so you want to find the smallest good number greater than or equal to nn.

The positive integer is called good if it can be represented as a sum of distinct powers of 33 (i.e. no duplicates of powers of 33 are allowed).

For example:

  • 3030 is a good number: 30=33+3130=33+31,
  • 11 is a good number: 1=301=30,
  • 1212 is a good number: 12=32+3112=32+31,
  • but 22 is not a good number: you can't represent it as a sum of distinct powers of 33 (2=30+302=30+30),
  • 1919 is not a good number: you can't represent it as a sum of distinct powers of 33(for example, the representations 19=32+32+30=32+31+31+31+3019=32+32+30=32+31+31+31+30 are invalid),
  • 2020 is also not a good number: you can't represent it as a sum of distinct powers of 33 (for example, the representation 20=32+32+30+3020=32+32+30+30 is invalid).

Note, that there exist other representations of 1919 and 2020 as sums of powers of 33 but none of them consists of distinct powers of 33.

For the given positive integer nn find such smallest mm (n≤mn≤m) that mm is a good number.

You have to answer qq independent queries.

Input

The first line of the input contains one integer qq (1≤q≤5001≤q≤500) — the number of queries. Then qq queries follow.

The only line of the query contains one integer nn (1≤n≤10181≤n≤1018).

Output

扫描二维码关注公众号,回复: 10638947 查看本文章

For each query, print such smallest integer mm (where n≤mn≤m) that mm is a good number.

Example

Input

8
1
2
6
13
14
3620
10000
1000000000000000000

Output

1
3
9
13
27
6561
19683
1350851717672992089

题意,一个数能否用3的幂次方相加得到,幂不能相同,满足就是好数,求最小的(大于或等于给出的数)的好数

题解 将输入数据转为三进制数,从高位往低位找到第一个为2的位置,再从第一个为2的位置向高位找到第一个为0

的位置,将这个为0的位置的值改为1并舍去所有低位的数,这个数即是我们要输出的数。而如果找不到一个2,说明

这个数本身就是一个好数。

举例 对一个数求它的三进制,通过while循环得到1020102,但这是倒着储存的,正确次序为2010201,因为好数中

是不含2的,要从高位找到一个二,再找到这个二前边的0,2010201等于02010201,把这个零改为1,然后把后边

的数舍去,为10000000,因为三进制中只有0,1,2这个2已经是最大的了,所以选择把它前边的0改为1,如果要是

这个2前边有1,把1改成2那就不是好数了(如果0前边还有1的话,那么计算的时候不能忘了它,如10201,改完是11000)

#include<stdio.h>
#include<string.h>
long long a[11000];
long long ti(long long x,long long y)    //快速幂
{
    long long s=1;
    while(y)
    {
        if(y&1)
            s=s*x;
        x=x*x;
        y>>=1;
    }
    return s;
}

int main()
{
    int q;
    scanf("%d",&q);
    while(q--)
    {
        memset(a,0,sizeof(a));
        long long n,i,j,v,k=0,ans=0,d;
        scanf("%lld",&n);
        d=n;
        while(n)
        {
            a[++k]=n%3;   //从低位开始存
            n=n/3;
        }
        for(i=k;i>=1;i--)
        {
            if(a[i]==2)
                break;
        }
        if(!i)
            printf("%lld\n",d);
        else
        {
            for(i++;;i++)
            {
                if(a[i]==0||i>k)
                {
                    a[i]=1;
                    break;
                }
            }
            if(i>k)
                ans=ti(3,i-1);
            for(;i<=k;i++)
            {
                if(a[i]==1)
                    ans=ans+ti(3,i-1);
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}
 

发布了30 篇原创文章 · 获赞 1 · 访问量 226

猜你喜欢

转载自blog.csdn.net/weixin_46204099/article/details/105322798
今日推荐