#数论-模运算#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,以及两个对应 ...
随机推荐
- ios开发屏幕问题
1. 程序要要支持Iphone 和 ipad,所以首先必需创建一通用程序,这一操作只要在创建程序时在 devices那栏上勾选universal即可,完成后会发现有两个.xib文件,但只有一个view ...
- python 爬虫总结【转】
1.基本抓取网页 get方法 import urllib2 url = "http://www.baidu.com" response = urllib2.urlopen(url) ...
- C语言和C++篇
C语言和C++篇 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的.想想我们至今的代码,到底生成和使用了多少String!标题上所罗列的语言,可以看成 ...
- C/C++单链表
C/C++单链表 先看例子,例1:定义链表 //定义链表 struct stu { int name; int age; struct stu *next; }; 用一组地址任意的存储单元存放线性表中 ...
- 用android代码显示图片的一部分源码
ShowPoritionPictureActivity代码: [java] <span style="font-size:16px;"> package com.iwi ...
- Html中DIV成为超级链接,解决在360浏览器+IE9显示小手图标的兼容性!
Html中DIV成为超级链接,解决在360浏览器+IE9显示小手图标的兼容性! <div style="cursor:pointer;" onclick="sele ...
- .Net程序员学用Oracle系列(2):准备测试环境
<.Net程序员学用Oracle系列:导航目录> 本文大纲 1.创建说明 1.1.为什么要创建的测试环境? 1.2.了解 Oracle 实例的默认用户 2.创建环境 2.1.创建基本环境 ...
- java中的ArrayList 、List、LinkedList、Collection关系详解
一.基础介绍(Set.List.Map) Set(集):集合中的元素不按特定方式排序,并且没有重复对象.他的有些实现类能对集合中的对象按特定方式排序. List(列表):集合中的元素按索引位置排序,可 ...
- linux c 需要掌握的技能大概——前辈的话
gcc+gdb+makefile+vi是一套组合,不能单纯的拆分开来学习. gcc主编译单个文件 gdb调试 makefile用于大型工程解决不同源文件的依赖关系 vi/emacs是编辑器 如果有条件 ...
- centos tomcat 安装
安装说明 安装环境:CentOS-6.3 安装方式:源码安装 软件:apache-tomcat-7.0.29.tar.gz 下载地址:http://tomcat.apache.org/downloa ...