链接:https://ac.nowcoder.com/acm/contest/338/L
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
Consider digits strings with length n, how many different strings have the sum of digits are multiple of 4?
输入描述:
There are several test cases end with EOF. For each test case, there is an integer in one line: n, the length of the digits string. (1≤n≤1,000,000,000).
输出描述:
For each case, output the number of digits strings with length n have the sum of digits are multiple of 4 in one line. The numbers maybe very large, you should output the result modular 2019.
示例1
输入
复制
1 2 3 4
输出
复制
3 25 249 479
题目大意:
• 求长度为n的数字串中,有多少个这样数字串,其数字之和是4的倍数(包括0)
• 输入: 每组测试数据一行,包含一个正整数n( 1 ≤ c≤109)
• 输出: 对于每组测试数据,输出一行,包含一个整数,表示有多少个这样数字串,其数字之和是4的倍数(包括0)。因为这个结果很大,所以将值模2019输出
• 本题快速幂,复杂度为O( logn)。标程在1000组测试数据下的运行时间约为60毫秒(第二标程运行时间约30毫秒)。建议时间限制为1秒,空间限制为64M
分析:(本题笔者掌握不是太好,如有解释不当的地方,恳请指正!)
矩阵
• 3 2 2 3
• 3 3 2 2
• 2 3 3 2
• 2 2 3 3
• 有四个特征根,分别是0, 10, 1+i, 1-i;
• 所以a
n=x10n+ycos(nπ/4)+zsin(nπ/4),根据
a1=3,a2=25,a3=249,可得:
• a
n=(10n+2sqrt(2)ncos(nπ/4))/4;
• 由快速幂求得答案。
#include <stdio.h>
#define M 2019
int rt[2][32],et[8]={2,2,0,-4,-8,-8,0,16};
int FPow(int f,int n)
{
int r=1,m=0;
while(n)
{
if(n&1)r=(r*rt[f][m])%M;
m++;
n>>=1;
}
return r;
}
int cal(int n)
{
int r1,r2;
r1=FPow(0,n);
r2=((FPow(1,n/8)*et[n%8])%M+M)%M;
return ((r1+r2)*505)%M;
}
int main()
{
int n,i;
rt[0][0]=10;rt[1][0]=16;
for(i=1;i<32;++i)
{
rt[0][i]=(rt[0][i-1]*rt[0][i-1])%M;
rt[1][i]=(rt[1][i-1]*rt[1][i-1])%M;
}
while(scanf("%d",&n)!=EOF&&n>0)
printf("%d\n",cal(n));
return 0;
}