Time Limit: 1000 MS


In mathematics, the factorial of a positive integer number n is written as n! and is de ned as follows:

n! = 1  2  3  4  : : :  (n  1)  n =

∏n

i=1

i

The value of 0! is considered as 1. n! grows very rapidly with the increase of n. Some values of n!

are:

0! = 1

1! = 1

2! = 2

3! = 6

4! = 24

5! = 120

10! = 3628800

14! = 87178291200

18! = 6402373705728000

22! = 1124000727777607680000

You can see that for some values of n, n! has odd number of trailing zeroes (eg 5!, 18!) and for some

values of n, n! has even number of trailing zeroes (eg 0!, 10!, 22!). Given the value of n, your job is to

nd how many of the values 0!; 1!; 2!; 3!; : : : ;(n  1)!; n! has even number of trailing zeroes.

Input

Input le contains at most 1000 lines of input. Each line contains an integer n (0  n  10

18

). Input

is terminated by a line containing a `-1'.

Output

For each line of input produce one line of output. This line contains an integer which denotes how

many of the numbers 0!; 1!; 2!; 3!; : : : ; n!, contains even number of trailing zeroes.

Sample Input

2

3

10

100

1000

2000

3000

10000

100000

200000

-1

Sample Output

3

4

6

61

525

1050

1551

5050

50250

100126

题意:给定一个数n。判定0! , 1! , 2!, ... , n!这(n+1)个阶乘有多少个末尾0的个数为偶数。 (0<=n<=10^18)

思路:i!末尾0个数取决于阶乘中5的个数。我们以5个数为一个总体。

1(5) 1(10) 1(15) 1(20) 2(25) 1(30) 1(35) 1(40) 1(45) 2(50) 1(55) 1(60) 1(65) 1(70) 2(75) 1(80) 1(85) 1(90) 1(95)  2(100) 1(105) 1(110)

1(115) 1(120) 3(125)  前一个数代表这个数中5的幂,后一个代表那个数。

我们将625曾经的数分组例如以下:

1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 3

1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 3

1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 3

1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 3

1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 4

那么哪些段是满足末尾0的个数为偶数呢? 我们将第一行的段表示出来,(y)为是,(n)为否

(y)1 (n) 1 (y) 1 (n) 1 (y) 2 (y) 1 (n) 1 (y) 1 (n) 1 (y) 2 (y) 1 (n) 1 (y) 1 (n) 1 (y) 2 (y) 1 (n) 1 (y) 1 (n) 1 (y) 2 (y) 1 (n) 1 (y) 1 (n) 1 (y) 3

我们发现:

(1)已知直到出现第一个5的k次幂的大段,那么直到出现第一个5的(k+1)次幂的大段一定是5的k次幂的大段反复5段,且最后一段的最后

一个元素把k换成(k+1)即为直到出现第一个5的(k+1)次幂的大段。

(2)已知直到出现第一个5的k次幂的大段中每一个小段的y/n情况,那么能够推知第一个5的(k+1)次幂的大段的每一个小段的y/n情况。

1.假设k是偶数。那么接下来的4个段与之前的段情况全然同样。

2.假设k是奇数,那么接下来的4段中,第2和第4段与之前段的情况同样。

第1和第3段与之前段的情况正好相反。

设dp[ i ][ 0 ]表示分组后直到出现第一个5的i次幂时。之前满足末尾0的个数为偶数的段的个数。

dp[ i ][ 1 ] 就是与上述情况相反的偶数的个数

那么

dp[ i ][ 0 ]=5 *dp[ i-1 ][ 0 ]       i为奇数;

dp[ i ][ 0 ]=3 *dp[ i ][ 0 ] + 2 *dp[
i ][ 1 ]     i为偶数;

dp[ i ][ 1 ] = a [ i - 1 ] - dp[ i ][ 0 ];

预处理完dp数组之后,对于n,我们每次二分找不大于n的最大次幂区间, 最好还是设为k,x= n /  a[ k ],那么n -= a[ k ] * x; 同一时候依据k的奇

偶性,更新ans。同一时候我们设了一个变量now记录当前的状态.

#include <iostream>
#include <algorithm>
#include <cstdio>
#define LL long long
using namespace std;
const int maxn=27; LL n,a[maxn],dp[maxn][2]; void initial()
{
LL t,sum=1;
a[0]=1;
for(int i=1;i<maxn;i++) a[i]=5*a[i-1]; dp[0][0]=1,dp[0][1]=0; // 这个赋值是为了后面好算。不是5倍的 ,以下都是5倍的。
dp[1][0]=1,dp[1][1]=0;
for(int i=2;i<maxn;i++)
{
if(i%2==0) dp[i][0]=3*dp[i-1][0]+2*dp[i-1][1];
else dp[i][0]=5*dp[i-1][0];
dp[i][1]=a[i-1]-dp[i][0];
} for(int i=1;i<maxn;i++)
{
dp[i][0]*=5;
dp[i][1]*=5;
}
} void solve()
{
LL ans=0;
if(n<=4) ans=n+1;
else
{
bool now=0;
n++;
while(n)
{
int t=upper_bound(a,a+maxn,n)-a-1;
LL num=n/a[t];
n=n%a[t];
if(t==0) ans+=num*dp[t][now];
else if(t%2==1) ans=ans+(num+1)/2*dp[t][now]+num/2*dp[t][now^1];
else ans=ans+num*dp[t][now]; n=n%a[t];
if(t%2==1 && num%2==1) now^=1;
}
}
cout<<ans<<endl;
} int main()
{
initial();
while(cin>>n)
{
if(n==-1) break;
solve();
}
return 0;
}

UVA 12683 Odd and Even Zeroes(数学—找规律)的更多相关文章

  1. UVa 12683 Odd and Even Zeroes(数论+数字DP)

    意甲冠军: 要求 小于或等于n号码 (0<=n <= 1e18)尾数的数的阶乘0数为偶数 思考:当然不是暴力,因此,从数论.尾数0数为偶数,然后,它将使N阶乘5电源是偶数.(二指数肯定少5 ...

  2. # E. Mahmoud and Ehab and the xor-MST dp/数学+找规律+xor

    E. Mahmoud and Ehab and the xor-MST dp/数学/找规律 题意 给出一个完全图的阶数n(1e18),点由0---n-1编号,边的权则为编号间的异或,问最小生成树是多少 ...

  3. Harmonic Number (II) 数学找规律

    I was trying to solve problem '1234 - Harmonic Number', I wrote the following code long long H( int  ...

  4. 数学/找规律/暴力 Codeforces Round #306 (Div. 2) C. Divisibility by Eight

    题目传送门 /* 数学/暴力:只要一个数的最后三位能被8整除,那么它就是答案:用到sprintf把数字转移成字符读入 */ #include <cstdio> #include <a ...

  5. HDU 5914 Triangle 数学找规律

    Triangle 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5914 Description Mr. Frog has n sticks, who ...

  6. ural 2029 Towers of Hanoi Strike Back (数学找规律)

    ural 2029 Towers of Hanoi Strike Back 链接:http://acm.timus.ru/problem.aspx?space=1&num=2029 题意:汉诺 ...

  7. HDU 1273 漫步森林(数学 找规律)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1273 漫步森林 Time Limit: 2000/1000 MS (Java/Others)    M ...

  8. SGU 105 数学找规律

    观察一下序列,每3个数一组,第一个数余1,不能,加第二个数后整除(第二个数本身余2),第三数恰整除.一行代码的事.011011011.... #include<iostream> usin ...

  9. UVA - 808 Bee Breeding (建立坐标系&找规律)

    题目: 输入两个格子的编号a和b(a,b≤10000),求最短距离.例如,19和30的距离为5(一条最短路是19-7-6-5-15-30). 思路: 如图建立坐标系,然后看两个点的向量如果位于二四象限 ...

随机推荐

  1. 10 在C#中读取文件

    我们在前一个练习中已经了解了如何在C#控制台程序(console)中读取用户的输入.现在我们要学习如何从一个文件中读取内容.在下面的练习中,你要格外小心.关于文件的操作,一不小心会损失你的重要文件. ...

  2. Redis主从复制失败(master_link_status:down)

    今天配置redis主从复制时出现master_link_status:down提示. 首先打开slave的redis.conf配置文件,确定slaveof 和masterauth 两个选项配置是否正确 ...

  3. 安装nodejs6.9x以后,原来在nodejs4.2.x中运行正常的ionic项目出现问题的解决

    安装nodejs6.9x以后,原来在nodejs4.2.x中运行正常的程序出现的问题.看错误信息,由于NodeJs版本升级导致的. 到提示的目录下运行:npm rebuild node-sass -g ...

  4. atom 插件安装【转载】

    http://www.cnblogs.com/20145221GQ/p/5334762.html 问题: 输入apm install后,可能一直没有响应,要强行退. 不知道安装的时候可不可以打开ato ...

  5. C# 获取当年的周六周日

    public void GetWMDay() { List<string> list = new List<string>(); "; DateTime counYe ...

  6. PHP 之文件锁解决并发问题

    一.参数说明 $handle: 文件资源 $operation: 锁的类型 LOCK_SH: 共享锁 LOCK_EX: 排他锁 LOCK_UN: 释放锁 $wouldblock: 设置为true的时候 ...

  7. 删除Git服务器文件但是保留本地文件

    参考: https://blog.csdn.net/u012804886/article/details/83059315 https://www.cnblogs.com/wfsovereign/p/ ...

  8. php银联支付

    简介 PHP银联支付 流程 1.注册 银联 - 技术开发平台和商户服务平台 https://open.unionpay.com 注意:注册时建议使用IE浏览器,之前注册时插件老是用不了,使用IE10以 ...

  9. 【转】关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念

    关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念 笔者是个刚刚踏入压力测试领域不到2个月的小菜,这里分享一下线程组中3个参数之间关系的个人见解,不喜请!喷!,望大家 ...

  10. VMware虚拟机下Ubuntu安装VMware Tools详解

    一.安装步骤 1.开启虚拟机,运行想要安装VMware Tools的系统,运行进入系统后,点击虚拟机上方菜单栏的“虚拟机(M)”->点击“安装 VMware Tools”,图片所示是因为我已经安 ...