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 ...
随机推荐
- Oracle PL/SQL 入门
PL/SQL 全称:Procedure Language/SQL.产生背景自己去百度. 模板: Declare ---变量定义 num ; name ) := 'damon'; idesc cnt_i ...
- TRIGGER command denied to user 'root'@'LAPTOP-M7KUFN86' for table 'growtest' | Table 'MyDatabase.tmpIdentity_Invites' doesn't exist
是因为创建表的时候,用户权限不够 NaviCat for Mysql 用这个工具打开MYSQL 在用户 下找到 root@% 这个用户,双击打开 设置服务器权限,最后两个权限勾上就OK 了,需要把MY ...
- HTTP 状态代码表示什么意思?
HTTP 状态代码表示什么意思? 如果某项请求发送到您的服务器要求显示您网站上的某个网页,服务器将会返回 HTTP 状态码响应请求.此状态代码提供关于请求状态的信息,一些常见的状态代码为: 200 - ...
- Scala入门之Array
/** * 大数据技术是数据的集合以及对数据集合的操作技术的统称,具体来说: * 1,数据集合:会涉及数据的搜集.存储等,搜集会有很多技术,存储现在比较经典的是使用Hadoop,也有很多情况使用Kaf ...
- nodejs学习之实现简易路由
此前实现了个数据转发功能,但是要建本地服务器,还需要一个简易的路由功能.因为只是用于本地服务器用于自己测试用,所以不需要太完善的路由功能,所以也就不去使用express框架,而是自己实现一个简易路由, ...
- C语言字符串与数字相互转换
在C/C++语言中没有专门的字符串变量,通常用字符数组来存放字符串.字符串是以“\0”作为结束符.C/C++提供了丰富的字符串处理函数,下面列出了几个最常用的函数. ● 字符串输出函数puts. ● ...
- C++之父Bjarne Stroustrup提供的关于异常处理的建议
节选自<The C++ Programming Language> ——C++之父Bjarne Stroustrup 1. Don’t use exceptions wh ...
- CSS中margin与padding的区别
CSS边距属性定义元素周围的空间.通过使用单独的属性,可以对上.右.下.左的外边距进行设置.也可以使用简写的外边距属性同时改变所有的外边距.——W3School 边界(margin):元素周围生成额外 ...
- “CEPH浅析”系列之八——小结
最初决定写这些文章的时候,本打算大致记录一下,几千字也就了事了.可是越写越觉得东西多,不说明白总有些不甘心,于是就越写越长,到这儿为止貌似已经有一万七千多字了.除了博士论文之外,应该是没有写过更长的东 ...
- hello Cookie
Cookie 是什么? Cookie在浏览器中的表现为请求头域和响应头域的字段,也就是伴随着请求和响应的一组键值对的文本.Cookie来源于服务器,第一次请求无Cookie参数,增加Cookie通过服 ...