#数论-模运算#POJ 1150、1284、2115
1.POJ 1150 The Last Non-zero Digit #质因数分解+模运算分治#
先贴两份题解:
http://www.hankcs.com/program/algorithm/poj-1150-the-last-non-zero-digit.html
http://www.cppblog.com/abilitytao/archive/2009/10/31/99907.html
下面是自己看完题解(划掉)之后的理解:
题目要求出组合数Anm=n!/(n-m)!(说实话一开始不知道题目中的NPM到底什么意思。。)的最后一个非零位,那么可以来看看n!的最后一个非零位该如何求得。
求n!:
(1)首先,n!的所有10因子都是要去掉的(因为求非零位),那么2和5也要一对一对的去掉;
(2)接下来把数列分成奇数列:1 2 3 4 5 6 7 8 9 10 –> 1 3 5 7 9 | 2 4 6 8 10
故有f(n )=f(n/2 )+g(n );
g(n )可以再分为:1 3 5 7 9 11 13 17 19 21 ……和5的奇数倍 5 15 25……
故设这个数列中末尾为x(x=1,3,7,9)的个数 g(n,x )=n/10+(n%10>=x)+g(n/5,x );
(3)最后再对数列中末尾为2和5的个数进行比较、特判一下即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std; //计算n!中质因子(2/5)的出现次数
int get_2_5(int n,int num)
{
if(n==0) return 0;
return n/num+get_2_5(n/num,num);
} //计算奇数数列中末尾为x的数的出现次数
int g(int n,int x)
{
if(n==0) return 0;
return n/10+(n%10>=x)+g(n/5,x);
//数列还能再次分出子问题,故有g(n/5,x)
} //计算数列中末尾为x的数的出现次数
int getx(int n,int x)
{
if(n==0) return 0;
return getx(n/2,x)+g(n,x);
} int table[4][4]={
6,2,4,8,//2^n%10的循环节
1,3,9,7,//3
1,7,9,3,//7
1,9,1,9 //9
}; int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
int num2=get_2_5(n,2)-get_2_5(n-m,2);
int num5=get_2_5(n,5)-get_2_5(n-m,5);
int num3=getx(n,3)-getx(n-m,3);
int num7=getx(n,7)-getx(n-m,7);
int num9=getx(n,9)-getx(n-m,9); int res=1;
if(num2<num5)
{
printf("5\n");
continue;
}
else
{
if(num2!=num5)
{//if num2==num5 那么res应该*1
res*=table[0][(num2-num5)%4];
res%=10;
} res*=table[1][num3%4];
res%=10;
res*=table[2][num7%4];
res%=10;
res*=table[3][num9%4];
res%=10;
}
printf("%d\n",res);
}
}
2.POJ 1284 Primitive Roots #欧拉函数#
有一个关于原根的概念:若p有原根,则它恰有φ(φ( p))个不同的原根。
欧拉函数定义:对于正整数p,<=p且与p互质的正整数(包括1)的个数记作φ( p)。
这道题其实就是求欧拉数。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; int Euler(int n)
{
int res=n;
for(int i=2;i*i<=n;i++)
{
while(n%i==0)
{
n/=i; res-=(res/i);
while(n%i==0)
n/=i;
}
}
if(n>1)
res-=(res/n);
return res;
} int main()
{
int p;
while(~scanf("%d",&p))
printf("%d\n",Euler(p-1));
return 0;
}
3.POJ 2115 C Looooops #扩展欧几里得#
http://blog.csdn.net/lyy289065406/article/details/6648546
题意:
对于C,for(i=A ; i!=B ;i +=C),在k位存储系统中循环几次才结束。
(若在有限次内结束,则输出循环次数n,否则输出FOREVER)
分析推导就直接看大牛的了,代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdlib>
#include<vector>
#include<stack>
#include<map>
using namespace std;
typedef long long ll; ll extend_gcd(ll a,ll b,ll &x,ll &y)
{ //return d=gcd(a,n);
if(b==0)
{
x=1,y=0;
return a;
}
else
{
ll t=extend_gcd(b,a%b,x,y);
ll xx=x,yy=y;
x=yy;
y=xx-(a/b)*yy;
return t;
}
} int main()
{
ll A,B,C,k,x,y;
while(~scanf("%I64d %I64d %I64d %I64d",&A,&B,&C,&k))
{
if(A==0&&B==0&&C==0&&k==0) break;
ll a=C,b=B-A,n=(ll)1<<k; //n=2^k
ll d=extend_gcd(a,n,x,y); if(b%d!=0) //方程无解
printf("FOREVER\n");
else
{
x=(x*(b/d))%n; //x为方程ax=b(mod n)的最小解
x=(x%(n/d)+n/d)%(n/d); //x为方程ax=b(mod n)的最小整数解
printf("%I64d\n",x);
}
}
return 0;
}
#数论-模运算#POJ 1150、1284、2115的更多相关文章
- 数论 : 模运算法则(poj 1152)
题目:An Easy Problem! 题意:求给出数的最小进制. 思路:暴力WA: discuss中的idea: 给出数ABCD,若存在n 满足 (A* n^3 +B*n^2+C*n^1+D*n^0 ...
- POJ 1150 The Last Non-zero Digit 数论+容斥
POJ 1150 The Last Non-zero Digit 数论+容斥 题目地址: id=1150" rel="nofollow" style="colo ...
- poj 3980 取模运算
取模运算 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10931 Accepted: 6618 Description ...
- 最后一个非零数字(POJ 1604、POJ 1150、POJ 3406)
POJ中有些问题给出了一个长数字序列(即序列中的数字非常多),这个长数字序列的生成有一定的规律,要求求出这个长数字序列中某个位上的数字是多少.这种问题通过分析,找出规律就容易解决. 例如,N!是一个非 ...
- java 取模运算% 实则取余 简述 例子 应用在数据库分库分表
java 取模运算% 实则取余 简述 例子 应用在数据库分库分表 取模运算 求模运算与求余运算不同.“模”是“Mod”的音译,模运算多应用于程序编写中. Mod的含义为求余.模运算在数论和程序设计中 ...
- mysql中的优化, 简单的说了一下垂直分表, 水平分表(有几种模运算),读写分离.
一.mysql中的优化 where语句的优化 1.尽量避免在 where 子句中对字段进行表达式操作select id from uinfo_jifen where jifen/60 > 100 ...
- c++ 模运算
在数学里,"模运算"也叫"求余运算",用mod来表示模运算. 对于 a mod b 可以表示为 a = q(商)*b(模数) + r(余数),其中q表示商,b表 ...
- 二分求幂/快速幂取模运算——root(N,k)
二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...
- Numpy 基本除法运算和模运算
基本算术运算符+.-和*隐式关联着通用函数add.subtract和multiply 在数组的除法运算中涉及三个通用函数divide.true_divide和floor_division,以及两个对应 ...
随机推荐
- C#获取友好时间差
/// <summary> /// 获取时间差 /// </summary> /// <param name="dtOld">要减的时间< ...
- [google面试CTCI] 2-3 只给定链表中间节点指针,如何删除中间节点?
[链表] Q:Implement an algorithm to delete a node in the middle of a single linked list, given only acc ...
- Oracle和Mysql分别生成sequence序列
有时候在往数据库中插入数据的时候,如果ID值是32位的UUID, 而自己随便写个字符又不合适,这时就要用到函数来产生一个序列值 Oracle: select sys_guid() from dual; ...
- 基于easyui的webform扩展
基于easyui的webform扩展 回顾 <前端基于easyui的mvc扩展>.<前端基于easyui的mvc扩展(续)>前两篇介绍了mvc内如何基于easyui进行扩展,在 ...
- npm 安装与常用命令
下载nodejs并安装,会附带安装npm工具https://nodejs.org/en/download/ npm 常用命令#在执行命令时需要管理员权限,mac请用sudo来执行,windows请使用 ...
- MVC从视图传参到Controller几种方式
简单数组传递 var array = ["aaa", "bbb", "ccc"]; $.ajax({ url:"@Url.Acti ...
- 为什么不能在子类或外部发布C#事件
为什么不能在子类或外部发布C#事件 背景 一个朋友问了一个问题:“为什么不能在子类或外部发布C#事件?”,我说我不知道,要看看生产的IL代码,下面我们看看. 测试 代码 1 using System; ...
- iOS GCD中级篇 - dispatch_group
1.关于dispatch_group 把一组任务提交到队列中,这些队列可以不相关,然后监听这组任务完成的事件. 最常见的几个方法: 1.dispatch_group_create创建一个调度任务组 2 ...
- Ubuntu下JDK+Tomcat+MySql环境的搭建
主机在阿里云上,所以网络的配置都省了,只剩下软件的安装和配置 1.安装mysql 1.1 apt-get install mysql-server-5.5 安装过程中,有两次提示输入 mysql 的 ...
- 怎样清除SWAP里的文件
在vim 编辑一个文件时断了网,文件就留在SWAP里,但我再vim这个文件保存后,再打开时又提示SWAP里有这文件了,此时swapoff -a后再ls -al查看,把文件所在目录里*.swp结尾的文件 ...