poj3696 快速幂的优化+欧拉函数+gcd的优化+互质
这题满满的黑科技orz
题意:给出L,要求求出最小的全部由8组成的数(eg: 8,88,888,8888,88888,.......),且这个数是L的倍数
sol:全部由8组成的数可以这样表示:((10^x)-1)*(8/9)
那么有m=((10^x)-1)*(8/9)=k*L,answer即满足条件的最小的x
性质1:若ax=by且a和b互质,那么说明a中没有任何b的质因子,b的质因子一定都在x里。所以x是b的倍数。
所以先想方设法在等式中构造两个互质的数以便化简。我们取p=8/gcd(8,L),q=9*L/gcd(8,L)
那么有p*((10^x)-1)=q*k,且p与q互质【8/gcd(8,L)与L/gcd(8,L)一定互质。8又没有3这个质因子,所以9*L/gcd(8,L)还是会互质】
所以由性质1,(10^x)-1是q的倍数。
所以(10^x)-1=0 (mod q)
(10^x)=1 (mod q)
性质2:欧拉定理。对于正整数a,n,若gcd(a,q)=1,则有a^phi(q)=1 (mod q) 【其中phi是欧拉函数】
这个式子是不是和上面很像呢~
所以若gcd(10,q)=1说明有解,否则无解
对于有解的情况,x=phi(q)就是一个解,但不一定是最小解。actually,0---phi(q)中还可能存在解。
性质3:因为后面有mod n,而余数都是有循环节的。(即一个循环周期的长度,设为r)
eg:如果有10^a=1 (mod q),那么10^(a+r)=1 (mod q)
首先x=0是一个解【10^0=1 (mod q)】。而且已经确定phi(q)也是一个解了。所以phi(q)一定是这个循环节r的倍数。
根据性质3,r肯定也是一个解。而且是最小的。
所以只要枚举phi(q)的约数,找出其中最小的满足条件的即可。
-----------------------接下来是满满的黑科技orz----------------------
Q1:本题数据很大,求gcd的过程会TLE肿么办
A1:因为gcd里面有一个数字是固定的,所以可以用一下黑科技
//q=9*N/gcd(8,N);
q=*N;
for (int i=;i<;i++)
if (q%==)
q=q/;
else break;
要求的是q/gcd(8,N)
而8分解质因数之后是2^3,也就是说带8的gcd里面最多也只可能有3个2。所以直接把这3个2能除掉的都除掉就行了
//if (gcd(10,q)!=1) ans=0;
if ((q%==)||(q%==))
ans=;
10的质因子只有2和5。如果q是2或5的倍数,就说明q和10不互质。
Q2:求快速幂取模(10^x)%q的时候,数据超了long long的范围,会出错
A2:这样:
LL func(LL a,LL b,LL c) //a*b%c
{
long long ret = ;
while (b)
{
if (b & )
ret = (ret + a) % c;
a = * a % c;
b >>= ;
}
return ret;
} LL pow_mod(LL a,LL b,LL MOD)
{
if (a==) return ;
LL t=a%MOD,ans=;
while(b)
{
if (b&)
ans=func(ans,t,MOD);
t=func(t,t,MOD);
b>>=;
}
return ans;
}
其实我也没看懂func是个什么鬼。。。。【逃
AC Code:
#include <iostream>
#include <cstdio>
using namespace std;
#define LL long long
#define MAXL 1000 LL TC=;
LL N,MOD,TM,q,ans;
int phi[MAXL+]; int gcd(int a,int b) //辗转相除法,返回gcd(a,b)
{
if (b==) return a;
return gcd(b,a%b);
} long long euler(long long n)
{
long long ret = n;
for (long long i = ; i * i <= n; i++)
if (n % i == )
{
ret = ret / i * (i - );
while (n % i == )
n /= i;
}
if (n > )
ret = ret / n * (n - );
return ret;
} /*
LL pow_mod(LL a,LL b,LL MOD)
{
if (a==1) return 1;
LL t=a%MOD,ans=1;
while(b)
{
if (b&1)
ans=ans*t%MOD;
t=t*t%MOD;
b>>=1;
}
return ans;
}
*/ LL func(LL a,LL b,LL c) //a*b%c
{
long long ret = ;
while (b)
{
if (b & )
ret = (ret + a) % c;
a = * a % c;
b >>= ;
}
return ret;
} LL pow_mod(LL a,LL b,LL MOD)
{
if (a==) return ;
LL t=a%MOD,ans=;
while(b)
{
if (b&)
ans=func(ans,t,MOD);
t=func(t,t,MOD);
b>>=;
}
return ans;
} int main()
{
//calc_phi(MAXL);
while (~scanf("%I64d",&N))
{
TC++;
if (N==) break;
//q=9*N/gcd(8,N);
q=*N;
for (int i=;i<;i++)
if (q%==)
q=q/;
else break; TM=euler(q); //tm=phi[q];
ans=TM;
//if (gcd(10,q)!=1)
if ((q%==)||(q%==))
ans=;
else
{
for (LL i=; i*i<=TM; i++)
if (TM%i==)
{
LL t1=i,t2=TM/i;
LL M1=pow_mod(,t1,q);
LL M2=pow_mod(,t2,q);
//cout<<t1<<" "<<M1<<endl<<t2<<" "<<M2<<endl;
if ((M1==)&&(t1<ans))
ans=t1;
if ((M2==)&&(t2<ans))
ans=t2;
}
}
printf("Case %d: ",TC);
cout<<ans<<endl;
}
} /*
LL len,tmp,N;
int TC=0;
bool ok; int main()
{
while(~scanf("%I64d",&N))
{
TC++;
if (N==0) break;
tmp=8;
len=1;
ok=false;
if (tmp%N==0) ok=true;
while ((!ok)&&(len<=MAXL))
{
tmp=tmp*10+8;
len++;
if (tmp%N==0)
ok=true;
}
if (ok)
printf("Case %d: %I64d\n",TC,len);
else
printf("Case %d: 0\n",TC);
} return 0;
}
*/
Reference:
http://www.cnblogs.com/rainydays/archive/2012/11/05/2754760.html
http://blog.csdn.net/yhrun/article/details/6908470
poj3696 快速幂的优化+欧拉函数+gcd的优化+互质的更多相关文章
- POJ-2888 Magic Bracelet(Burnside引理+矩阵优化+欧拉函数+逆元)
Burnside引理经典好题呀! 题解参考 https://blog.csdn.net/maxwei_wzj/article/details/73024349#commentBox 这位大佬的. 这题 ...
- HDU5780 gcd (BestCoder Round #85 E) 欧拉函数预处理——分块优化
分析(官方题解): 一点感想: 首先上面那个等式成立,然后就是求枚举gcd算贡献就好了,枚举gcd当时赛场上写了一发O(nlogn)的反演,写完过了样例,想交发现结束了 吐槽自己手速慢,但是发了题解后 ...
- 快速切题 sgu102.Coprimes 欧拉函数 模板程度 难度:0
102. Coprimes time limit per test: 0.25 sec. memory limit per test: 4096 KB For given integer N (1&l ...
- UVa 11426 (欧拉函数 GCD之和) GCD - Extreme (II)
题意: 求sum{gcd(i, j) | 1 ≤ i < j ≤ n} 分析: 有这样一个很有用的结论:gcd(x, n) = i的充要条件是gcd(x/i, n/i) = 1,因此满足条件的x ...
- 【hdu-2588】GCD(容斥定理+欧拉函数+GCD()原理)
GCD Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissio ...
- POJ 2480 Longge's problem 欧拉函数—————∑gcd(i, N) 1<=i <=N
Longge's problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6383 Accepted: 2043 ...
- [bzoj]2705: [SDOI2012]Longge的问题[数论][数学][欧拉函数][gcd]
[bzoj]P2705 OR [luogu]P2303 Longge的问题 Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需 ...
- UVA 11426 GCD - Extreme (II)(欧拉函数打表 + 规律)
Given the value of N, you will have to find the value of G. The definition of G is given below:Here ...
- Longge's problem(欧拉函数应用)
Description Longge is good at mathematics and he likes to think about hard mathematical problems whi ...
随机推荐
- Session一次错误记录
/// <summary> /// 验证登录状态是否已失效 /// </summary> /// <returns>< ...
- C#执行Javascript代码的几种方法
一.开源项目 Javascript .NET 地址: http://javascriptdotnet.codeplex.com/ 它是Google Chrome V8引擎在.NET上的封装,功能完善, ...
- npm中package.json详解
通常我们使用npm init命令来创建一个npm程序时,会自动生成一个package.json文件.package.json文件会描述这个NPM包的所有相关信息,包括作者.简介.包依赖.构建等信息,格 ...
- 抛开react,如何理解virtual dom和immutability
去年以来,React的出现为前端框架设计和编程模式吹来了一阵春风.很多概念,无论是原本已有的.还是由React首先提出的,都因为React的流行而倍受关注,成为大家研究和学习的热点.本篇分享主要就聚焦 ...
- Javascript中的循环变量声明,到底应该放在哪儿?
相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准 ...
- 用js转换joson返回数据库的时间格式为/Date(*************)/
原理是取中间的毫秒数,再转换成js的Date类型 function ChangeDateFormat(val) { if (val != null) { var date = new Date(par ...
- AVL树插入操作实现
为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...
- Android开发之Menu和actionBar
一.通过Menu目录下创建一个布局文件: 先看代码meu/main.xml: <?xml version="1.0" encoding="utf-8"?& ...
- webpack入坑之旅(一)不是开始的开始
最近学习框架,选择了vue,然后接触到了vue中的单文件组件,官方推荐使用 Webpack + vue-loader构建这些单文件 Vue 组件,于是就开始了webpack的入坑之旅.因为原来没有用过 ...
- PHP 异常
<?php /* PHP 异常处理 什么是异常? PHP 5 提供了一种新的面向对象的错误处理方法. 异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程. 这种情况称为异常. 当异常被 ...