Cirno's perfect math class is fashionable over the world. But now, sadly, it must be stopped for some reason. In the last class,N students attended, and each student gave a gift to Cirno. But the gifts are too many so that Cirno just want to takeK(K is non-negative) gifts away.
As we all know, Cirno loves the number ⑨. Assume there areP ways to take awayK gifts. IfP > 0 andP is a multiple of 9, Cirno will acceptK as an alternative plan. Now, Cirno want to know how many plans that she has to think over.
Input
The number of test cases T(integer, about 50) will be given in the first line. ThenT lines follow. and each line contains a non-negative integerN(N <= 10^1000).
Output
One line for each case, the answer.
Sample Input
35190
Sample Output
063
Source: ZOJ Monthly, January 2015
题意:
给定n(n<=10^1000),求满足0<=k<=n且C(n,k)是9的倍数的k的个数。
分析:
考虑C(n,k)不是9的倍数的k的个数,分为两部分求解,
(1)C(n,k)不被3整除,
由Lucas定理知,若n的三进制表示为a[0]a[1]a[2]...a[s],则所求的个数为res=(a[0]+1)*(a[1]+1)*(a[2]+1)*...*(a[s]+1),
(2)C(n,k)被3整除但不被9整除,
这种情况比较麻烦,Lucas定理不能发挥作用,考虑使用更一般的Kummer定理,
根据Kummer定理,C(n,k)中3的幂次即为在三进制下n减去k时发生借位的次数,那么当C(n,k)恰被3整除时,n减k时恰好发生了一次借位,也就是说,有且仅有一个t,使得k的三进制表示的第t位严格大于n的第t位,且k的第t+1位严格小于n的第t+1位。枚举所有位置,注意到对每个位置计算贡献时,结果只有两个因式与res不同,如果不考虑大数运算的复杂度,可以O(1)计算贡献.
以上两种情况之和ans即为不满足条件的k的个数,输出n+1-ans即可,复杂度O((logn)^2)。
Kummer定理相关:
代码:
import java.util.*;
import java.io.*;
import java.math.*;
public class Main
{
static public void main(String[] args)
{
Scanner cin=new Scanner(System.in);
int T=cin.nextInt();
for(int ca=1;ca<=T;ca++)
{
BigInteger n=cin.nextBigInteger();
String s=n.toString(3);
BigInteger res=BigInteger.ONE;
for(int i=0;i<s.length();i++)
{
res=res.multiply(BigInteger.valueOf(s.charAt(i)-'0'+1));
}
BigInteger ans=res;
for(int i=1;i<s.length();i++)
{
ans=ans.add(res.divide(BigInteger.valueOf(s.charAt(i-1)-'0'+1))
.divide(BigInteger.valueOf(s.charAt(i)-'0'+1))
.multiply(BigInteger.valueOf(s.charAt(i-1)-'0'))
.multiply(BigInteger.valueOf('2'-s.charAt(i))));
}
System.out.println(n.subtract(ans).add(BigInteger.ONE));
}
}
}