POJ 1150 The Last Non-zero Digit 数论+容斥
POJ 1150 The Last Non-zero Digit 数论+容斥
题目地址: id=1150" rel="nofollow" style="color:rgb(0,136,204);text-decoration:none;">POJ 1150
题意:
求排列P(n, m)后面第一个非0的数。
分析:
为了熟悉题目中的理论。我先做了俩0基础的题目: id=1401" rel="nofollow" style="color:rgb(0,136,204);text-decoration:none;">POJ 1401 pid=954" rel="nofollow" style="color:rgb(0,136,204);text-decoration:none;">NYOJ 954
1401 && ZOJ 2202 Factorial 阶乘N!的末尾零的个数
954 求N!二进制末尾几个0
这题想了一下。十进制末尾几个0能够转化为几个5因子。二进制最后一位非0能够转化为2因子。可是10进制就不行了,并且这个不是单单N!。而是n!/m!。orz。
实在太弱仅仅能研究题解,推荐SCAU_Lyon巨巨的题解和abilitytao巨巨的题解。
然后我坐在电脑前面看了一晚上题解,最终。我发现我太弱了,我好不easy有点看懂了。
大概讲一下吧。
我们要把排列转化成前面两题的形式。
P(n, m) = n!/(n-m)!,我们让m = n - m直接按n!/m!做,也就是求m∗(m+1)∗(m+2)∗....∗n了。
这时候,我们仅仅要统计在[m, n]这个范围里面的数的最后一位即可了,假设直接去暴力会跪。由于我们不仅要统计每一个数的最后一位,另一些2和5因子混在数中,我们还要消掉那些因子,然后取末位。
于是要把2和5抽出来,然后就仅仅剩3,7,9,统计抽完后的3,7,9,然后还得记得:由于这里面2可能会比5多,所以要把多出来的2算出来。
仅仅要知道怎样统计n!,就能统计排列。
个中计算有非常厉害的技巧,表示orz。
一、计算n!中消除2,5后末位为x的公式为:
f(n, x) = n/10 + (n%10>=x) + f(n/2, x) + f(n/2, 5) - f(n/10, x).
解释下:
1. x限定3,7,9。
2. n/10 + (n%10>=x)也就是:每十个数以内末数字是3,7,9在没有除去2和5两种因子前都仅仅会出现一次。
3. 加上抽出2和5后的子问题。(这里跟前面两题原理一样)
4. 抽出2和5的时候,会多抽出了一次10,这时候就要用容斥定理减去。
二、然后计算多余的2就比較easy理解了。就跟前面俩题一样。求出2的个数和5的个数。减一下就是n!中多出来的2的个数了。
三、然后我们就能得到[m,n]中抽出2,5后末位为3,7,9的个数,以及多出来的2的个数了。
这时候假设直接while(cnt--)去算可能会超时+爆范围。
我们能够发现2^n,3^n,7^n,9^n的末位都是有规律可寻的。于是就能直接算了。
具体细节见代码。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* File: 1150.cpp
* Create Date: 2014-05-26 22:28:45
* Descripton:
*/
#include <cstdio>
#include <cstring>
const int N = 2e5;
int cnt3, cnt7, cnt9, cnt2;
int n, m;
int rec[10][N];
// 计算n!中消除2,5后末位为x的数量
int f(int n, int k) {
if (n < 1)
return 0;
if (n < N && rec[k][n] != -1)
return rec[k][n];
int ret = n / 10 + (n % 10 >= k) + f(n / 2, k) + f(n / 5, k) - f(n / 10, k);
if (n < N)
rec[k][n] = ret;
return ret;
}
// 多出来的2的个数
int more(int n) {
int num2 = 0, num5 = 0;
int t = n;
while (t != 0) {
num2 += t / 2;
t /= 2;
}
while (n != 0) {
num5 += n / 5;
n /= 5;
}
return num2 - num5;
}
int main()
{
memset(rec, -1, sizeof(rec));
while (~scanf("%d%d", &n, &m)) {
if (m == 0) {
puts("1");
continue;
}
m = n - m;
cnt2 = more(n) - more(m);
cnt3 = f(n, 3) - f(m, 3);
cnt7 = f(n, 7) - f(m, 7);
cnt9 = f(n, 9) - f(m, 9);
// printf("%d %d %d %d\n", cnt2, cnt3, cnt7, cnt9);
// 2 4 8 6
if (cnt2-- == 0)
cnt2 = 1;
else if (cnt2 % 4 == 0)
cnt2 = 2;
else if (cnt2 % 4 == 1)
cnt2 = 4;
else if (cnt2 % 4 == 2)
cnt2 = 8;
else
cnt2 = 6;
// 1 3 9 7
if (cnt3 % 4 == 0)
cnt3 = 1;
else if (cnt3 % 4 == 1)
cnt3 = 3;
else if (cnt3 % 4 == 2) cnt3 = 9;
else
cnt3 = 7;
// 1 7 9 3
if (cnt7 % 4 == 0)
cnt7 = 1;
else if (cnt7 % 4 == 1)
cnt7 = 7;
else if (cnt7 % 4 == 2)
cnt7 = 9;
else
cnt7 = 3;
// 1 9
if (cnt9 % 2 == 0)
cnt9 = 1;
else
cnt9 = 9;
printf("%d\n", cnt2 * cnt3 * cnt7 * cnt9 % 10);
}
return 0;
}
POJ 1150 The Last Non-zero Digit 数论+容斥的更多相关文章
- Coprime (单色三角形+莫比乌斯反演(数论容斥))
这道题,先说一下单色三角形吧,推荐一篇noip的论文<国家集训队2003论文集许智磊> 链接:https://wenku.baidu.com/view/e87725c52cc58bd631 ...
- hdu1695:数论+容斥
题目大意: 求x属于[1,b]和 y属于[1,d]的 gcd(x,y)=k 的方案数 题解: 观察发现 gcd()=k 不好处理,想到将x=x/k,y=y/k 后 gcd(x,y)=1.. 即问题转化 ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) F - Cowslip Collections 数论 + 容斥
F - Cowslip Collections http://codeforces.com/blog/entry/43868 这个题解讲的很好... #include<bits/stdc++.h ...
- 数论 + 容斥 - HDU 4059 The Boss on Mars
The Boss on Mars Problem's Link Mean: 给定一个整数n,求1~n中所有与n互质的数的四次方的和.(1<=n<=1e8) analyse: 看似简单,倘若 ...
- 数论 + 容斥 - HDU 1695 GCD
problem's Link mean 给定五个数a,b,c,d,k,从1~a中选一个数x,1~b中选一个数y,使得gcd(x,y)=k. 求满足条件的pair(x,y)数. analyse 由于b, ...
- HDU - 2204 Eddy's爱好 (数论+容斥)
题意:求\(1 - N(1\le N \le 1e18)\)中,能表示成\(M^k(M>0,k>1)\)的数的个数 分析:正整数p可以表示成\(p = m^k = m^{r*k'}\)的形 ...
- 【bzoj2393】Cirno的完美算数教室 数论容斥
Description ~Cirno发现了一种baka数,这种数呢~只含有2和⑨两种数字~~ 现在Cirno想知道~一个区间中~~有多少个数能被baka数整除~ 但是Cirno这么天才的妖精才不屑去数 ...
- HDU 5514 Frogs (数论容斥)
题意:有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少? 析:首先可以知道的是第 i 只青蛙可以跳到 k * gcd(ai, m),然后我就计 ...
- UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)
题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...
随机推荐
- C#跨域
//在ConfigureServices中配置 #region 跨域 var urls = "*";//Configuration["AppConfig:Cores&qu ...
- Java基础知识(数据类型和集合)
一.数据类型 包装类型 包装类型是对基本数据类型不足之处的补充. 基本数据类型的传递方式是值传递,而包装类型是引用传递,同时提供了很多数据类型间转换的方法. Java1.5 以后可以自动装箱和拆箱 二 ...
- vue:使用不同参数跳转同一组件,实现动态加载图片和数据,以及利用localStorage和vuex持久化数据
需求:通过不同的参数复用同一组件,实现动态加载数据和图片,同时,在页面刷新时,图片依旧可以加载成功. 过程出现的bug和问题: 1.使用params传参后,再次刷新页面,参数丢失导致数据无法再次加载 ...
- Leetcode152. Maximum Product Subarray乘积的最大子序列
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6. 示例 2 ...
- Ubuntu 14.04 Ruby 2.3.3 安装
在Ubuntu 14.04通过下载Ruby源码包进行安装. 第一步,更新apt-get sudo apt-get update 通过apt-get安装ruby依赖 sudo apt-get insta ...
- SQL中distinct 和 row_number() over() 的区别及用法
1 前言 在咱们编写 SQL 语句操作数据库中的数据的时候,有可能会遇到一些不太爽的问题,例如对于同一字段拥有相同名称的记录,我们只需要显示一条,但实际上数据库中可能含有多条拥有相同名称的记录,从而在 ...
- 【codeforces 499C】Crazy Town
[题目链接]:http://codeforces.com/problemset/problem/499/C [题意] 一个平面,被n条直线分成若干个块; 你在其中的某一块,然后你想要要到的终点在另外一 ...
- jQuery3动画+创建元素
一.jQuery的动画 1.jQuery自带的动画 1>变化的是width height opacity display <!DOCTYPE html> <html lang= ...
- Django项目:CRM(客户关系管理系统)--70--60PerfectCRM实现CRM学生上课记录
#urls.py """PerfectCRM URL Configuration The `urlpatterns` list routes URLs to views. ...
- bootstrap字体图标在IE上不显示
最简单的办法就是直接下载最新的bootstrap.css替换掉旧的. 但是由于我做的项目直接替换会出现样式冲突问题,因此只好慢慢找是什么属性导致图标不显示,最后找到了解决办法: 1.首先保字体文件的位 ...