[NOIP2017模拟]Factorial Surplus Tail
2017-08-24 09:58
316 查看
题目描述
FST 作为 OIer ,经常会遇到和阶乘有关的问题,但是一个数的阶乘末尾总是会有很多 0 ,FST 认为这很不美观,但是 FST 觉得如果 0 的个数是偶数的话,还是可以接受的。
所以就有这样一个问题,FST 想知道 0!,1!,2!… … (n-1)!,n! 中有多少数的末尾 0 个数是偶数。(注意0!是1,0算偶数)
输入格式
读入有若干行,每行一个正整数 n ,最后一行是一个 -1 。
输出格式
对于每个 n 输出一行,为 0!,1!,2!… … (n-1)! ,n! 中末尾 0 个数是偶数的个数。
样例数据
输入
2
3
10
-1
输出
3
4
6
备注
【数据范围】
测试点 1、2:n≤10;数据组数=1;
测试点 3、4:n≤10000;数据组数=10;
测试点 5、6、7、8:n≤109;数据组数=105;
测试点 9、10:n≤1018;数据组数=105;
分析:
算法一: 最暴力的暴力 20%
直接把阶乘算出来数 0 的个数。
算法二: 较优美的暴力 40%
因为质因子 2 肯定比质因子 5 多(这个就不需要证明了吧) ,所以相当于统计质因
子 5 的个数,所以暴力可以写地更简单。
算法三: 分段打表 60%
我们可以每隔 100W 个数打个表,这样暴力复杂度为 O(106)。
算法四: 类 DP 算法 100%
第一次 DP,预处理计算[0,5k)的答案和 0 个数的奇偶变化,可以从 5k−1
转移。
可以观察下规律: (0 表示偶数,1 表示奇数)
k=0: 0
k=1: 00000
k=2: 0000011111000001111100000
k=3: 0000011111000001111100000000001111100000… …
有 2 种可能:
k是偶数, 那么 k-1是奇数, 0 个数的奇偶会变, ansk=3∗ansk−1+2∗(5k−1−ansk−1)
k是奇数,那么 k-1是偶数,0 个数的奇偶不会变,ansk=ansk−1∗5
第二次 DP,把 n+1 转化为 5 进制,从高位开始做。
然后我们可以分类讨论,例如当前位的数是 3,当前位是奇数位,现在的奇偶性为偶,那么转移答案为 ansk∗2+(5k−ansk)∗1,因为我们预处理的答案相当于从偶数开始,然后奇数位会改奇偶性,分配给 3 段就是(ansk) (ansk取反) (ansk)。
(可以不管它,我都看不懂这是什么鸟语,看下面模拟可能还好一点)
每次复杂度 O(log5n)
代码:
这个题不好理解,更不好解释,代码下方我会模拟一次
模拟
例如,现在的n为74(五进制244,是为了方便看加几次满足的),直接进入第二个dp,i=2时,加上两个52时满足的个数;i=1时,n还余下24,i为奇数,要取正取反取正取反;i=0时,n还余下4,i为偶数,i=1时刚好取反于是到这一步是取正了,加上四个1。最后还有一个数,由于i=0时没有取正取反,所以直接单独再加一个1。
本题结。
FST 作为 OIer ,经常会遇到和阶乘有关的问题,但是一个数的阶乘末尾总是会有很多 0 ,FST 认为这很不美观,但是 FST 觉得如果 0 的个数是偶数的话,还是可以接受的。
所以就有这样一个问题,FST 想知道 0!,1!,2!… … (n-1)!,n! 中有多少数的末尾 0 个数是偶数。(注意0!是1,0算偶数)
输入格式
读入有若干行,每行一个正整数 n ,最后一行是一个 -1 。
输出格式
对于每个 n 输出一行,为 0!,1!,2!… … (n-1)! ,n! 中末尾 0 个数是偶数的个数。
样例数据
输入
2
3
10
-1
输出
3
4
6
备注
【数据范围】
测试点 1、2:n≤10;数据组数=1;
测试点 3、4:n≤10000;数据组数=10;
测试点 5、6、7、8:n≤109;数据组数=105;
测试点 9、10:n≤1018;数据组数=105;
分析:
算法一: 最暴力的暴力 20%
直接把阶乘算出来数 0 的个数。
算法二: 较优美的暴力 40%
因为质因子 2 肯定比质因子 5 多(这个就不需要证明了吧) ,所以相当于统计质因
子 5 的个数,所以暴力可以写地更简单。
算法三: 分段打表 60%
我们可以每隔 100W 个数打个表,这样暴力复杂度为 O(106)。
算法四: 类 DP 算法 100%
第一次 DP,预处理计算[0,5k)的答案和 0 个数的奇偶变化,可以从 5k−1
转移。
可以观察下规律: (0 表示偶数,1 表示奇数)
k=0: 0
k=1: 00000
k=2: 0000011111000001111100000
k=3: 0000011111000001111100000000001111100000… …
有 2 种可能:
k是偶数, 那么 k-1是奇数, 0 个数的奇偶会变, ansk=3∗ansk−1+2∗(5k−1−ansk−1)
k是奇数,那么 k-1是偶数,0 个数的奇偶不会变,ansk=ansk−1∗5
第二次 DP,把 n+1 转化为 5 进制,从高位开始做。
然后我们可以分类讨论,例如当前位的数是 3,当前位是奇数位,现在的奇偶性为偶,那么转移答案为 ansk∗2+(5k−ansk)∗1,因为我们预处理的答案相当于从偶数开始,然后奇数位会改奇偶性,分配给 3 段就是(ansk) (ansk取反) (ansk)。
(可以不管它,我都看不懂这是什么鸟语,看下面模拟可能还好一点)
每次复杂度 O(log5n)
代码:
这个题不好理解,更不好解释,代码下方我会模拟一次
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<algorithm> #include<cctype> #include<iomanip> #include<queue> #include<set> using namespace std; long long getlong() { long long sum=0,f=1; char ch; for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;ch>='0'&&ch<='9';ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f; } long long n,mi[30],ans,num[30][2],tmp; int main() { freopen("fstagain.in","r",stdin); freopen("fstagain.out","w",stdout); mi[0]=1; for(int i=1;i<=25;++i)//预处理5的次方 mi[i]=mi[i-1]*5; num[0][0]=1;//num[i][0/1]表示[0,5^i)中有多少个0/1 for(int i=1;i<=25;++i)//根据规律预处理 if(i%2==1) { num[i][0]=num[i-1][0]*5; num[i][1]=num[i-1][1]*5; } else { num[i][0]=3*num[i-1][0]+2*num[i-1][1]; num[i][1]=3*num[i-1][1]+2*num[i-1][0]; } n=getlong(); while(n!=-1) { ans=0; tmp=0; for(int i=25;i>=0;--i)//第二次dp,结合下方模拟理解 { for(int j=1;j<=n/mi[i];++j) { ans+=num[i][tmp]; if(i%2==1) tmp^=1; } n%=mi[i]; } cout<<ans+num[0][tmp]<<endl;//因为我们的区间左闭右开,是[0,n-1],还差一个数,最后加上 n=getlong(); } return 0; }
模拟
例如,现在的n为74(五进制244,是为了方便看加几次满足的),直接进入第二个dp,i=2时,加上两个52时满足的个数;i=1时,n还余下24,i为奇数,要取正取反取正取反;i=0时,n还余下4,i为偶数,i=1时刚好取反于是到这一步是取正了,加上四个1。最后还有一个数,由于i=0时没有取正取反,所以直接单独再加一个1。
本题结。
相关文章推荐
- [NOIP模拟]Factorial Surplus Tail
- JZOJ 100036 【NOIP2017提高A组模拟7.10】随机
- 【JZOJ 4932】【NOIP2017提高组模拟12.24】B
- 5230. 【NOIP2017模拟A组模拟8.5】队伍统计
- JZOJ5379. 【NOIP2017提高A组模拟9.21】Victor爱数字
- [NOIP2017模拟]table
- JZOJ 5384. 【NOIP2017提高A组模拟9.23】四维世界
- [JZOJ5390]【NOIP2017提高A组模拟9.26】逗气
- 2017NOIP普及模拟赛题解报告
- [NOIP2017模拟]Xor
- JZOJ 5398. 【NOIP2017提高A组模拟10.7】Adore
- JZOJ5400. 【NOIP2017提高A组模拟10.7】Repulsed 树型DP+贪心
- [NOIP2017模拟]Fantasy Strange Tree
- [NOIP2017模拟]德充符
- [NOIP2017模拟][poj1091]跳蚤
- JZOJ 5195. 【NOIP2017提高组模拟7.3】A
- 【JZOJ 4931】【NOIP2017提高组模拟12.24】A
- JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计
- JZOJ 5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- 【JZOJ5232】【NOIP2017模拟A组模拟8.5】带权排序