#数论-模运算#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,以及两个对应 ...
随机推荐
- TLS之上的HTTP
1.介绍 HTTP[RFC2616]最初是在INTERNET上不用密码的应用.但随着HTTP的敏感性应用日益增加,对安全性的要求也随之增加.SSL及其后继TLS[RFC2246]提供了面向通道的安全性 ...
- 联想E430Cwindow8系统换成win7
垃圾win8系统各种不习惯,尤其无线网络老是自己断掉,忍无可忍只能换成win7,之前换过一次,没有成功,记得是提示硬盘模式要由GPT换成MBR. 这次换系统采用了PE里直接分区,格式化所有数据,然后g ...
- TCP可靠传输的实现
TCP可靠传输的实现 1.概述 为方便描述可靠传输原理,假定数据传输只在一个方向上进行,即A发送数据,B给出确认 2.以字节为单位的滑动窗口 TCP的滑动窗口是以字节为单位的.为了 ...
- Google论文之三----MapReduce
Google论文之三----MapReduce MapReduce:大型集群上的简单数据处理 摘要 MapReduce是一个设计模型,也是一个处理和产生海量数据的一个相关实现.用户指定一个用于处理一个 ...
- php memcached缓存集群
一.需求描述 一linode xen vps 1G RAM,40+sites,IO频繁,openfiles ulimit已65535 US时间访问量大增,nginx不定时502 二.解决办法 page ...
- android.database.CursorIndexOutOfBoundsException: Index <m> requested, with a size of <n>
遇到这样的问题比较郁闷,造成上述问题的原因也是多种多样的. 总结一下原因: 1:得到cursor对象,没有moveToPosition()或者moveToNext()等游标操作就进行cursor.ge ...
- 算法之prim算法
最小生成树是数据结构中图的一种重要应用,它的要求是从一个带权无向完全图中选择n-1条边并使这个图仍然连通(也即得到了一棵生成树),同时还要考虑使树的权最小. prim算法就是一种最小生成树算法. 普里 ...
- C#中的文件操作1
1. 文件操作常用相关类 a)File //操作文件,静态类,对文件整体操作.拷贝.删除.剪切等. b)Directory //操作目录(文件夹),静态类 c)Di ...
- ASP.NET中的C#基础知识
ASP.NET中的C#基础知识 说明:asp.net作为一种开发框架现在已经广为应用,其开发的基础除了前端的html.css.JavaScript等后端最重要的语言支持还是C#,下面将主要用到的基础知 ...
- 正则表达式之邮箱验证javascript代码
fuchangxi的正则: 复制代码 代码如下: /^([0-9A-Za-z\-_\.]+)@([0-9a-z]+\.[a-z]{2,3}(\.[a-z]{2})?)$/g 开始必须是一个或者多个单词 ...