湖南大学第十四届ACM程序设计大赛 L The Digits String

链接: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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值