hdu--4861--费马小定理&&素数的原根

可以用打表找规律过这题。  但这显然不是这题的初衷。

题意很简单 其实就是判断  var = ( 1^i + 2^i + ... + (p-1)^i ) ( mod p )//很重要的一个初始条件:p是素数

首先 你一定要知道费马小定理。

假如p是素数 并且p不整除a 那么 a^(p-1)≡1( mod p) <因为我这边没好的数学公式编辑器 我只能用文字来描述一些东西 >

我们发现 上面 var的式子中 下标值是从1-(p-1) 就满足了上面关于a的要求

那么当(p-1)|i 即(p-1)整除i 成立时 那么每一个小式子的值都是1 一共有p-1个式子 所以var = p-1

这题的难点是 求出 (p-1)与I没有整除关系的时候 var的值是多少

这边 又要涉及一个数学概念:原根

在a^(x)≡1( mod p)成立下 如果x的最小次数是 p-1 那么将a称为模p的原根。<每个素数p都是由原根的,确切地说,每个素数p都有 f(p-1)个模p的原根>

这边的f(z)函数是 欧拉函数         这也是可以证明的  我这边不写了 因为我觉得这个证明起来还是蛮麻烦的

对于模p的原根g来说

g^1,g^2,g^3....g^(p-1) mod p的值对应着1,2,3....p-1的不同次序的排列

下面我们来证明它的正确性。

假设g^i≡g^j(mod p) 那么p整除(g^i-g^j) //这边假设i>=j   这是没有关系的  因为i j必然存在一个大小关系 当然你可以说j>=i

p|(g^i-g^j) ->  p|( g^j * ( g^(i-j) - 1 )  因为 gcd( p , g^j ) = 1那么 p|g^(i-j)-1 也就是说

g^(i-j)-1 = k*p+1(k=0,1,2,3,....) 也就是说 g^(i-j)≡1( mod p) <看到这边 你是否想到了费马小定理>

现在让我们来推翻自己的假设

1<=j<=i<=p-1  ->   0<=i-j<=p-2 那么想要让 g^(i-j)≡1( mod p) 成立 只能使i-j=0了 那么 i == j了

所以 假设错误 不存在不同的i j使g^i , g^j 对P取模有不同的值  所以对于上面的那个结论正确性得证。

那么 我们就可以进行一个关键的转换步骤了

var = ( 1^i + 2^i + ... + (p-1)^i ) ( mod p )

var = ( g^1^i + g^2^i + ....+ g^(p-1)^i) ( mod p )//这边我转换的是 将 1^i+2^i+3^i+...+(p-1)^i整体进行等效替代的 因为是不同次序 但是中间的运算符是加号

var = ( g^i^1 + g^i^2 + ....+ g^i^(p-1) ( mod p )//你会惊喜地发现  现在变成一个等比式子  首项是g^i  并且公比也是g^i 我们现在求出它的数列和

Sn = (g^i) * ( 1-(g^i^(p-1) ) / ( 1-g^i )

Sn = (g^i) * ( 1-(g^(p-1)^i) ) / ( 1-g^i ) 因为g^(p-1)≡1 ( mod p )所以Sn = 0

注意下 在 (p-1)|i 时  分母为0  这时候 是不能进行等比求和计算的。

所以 最终我们只要考虑 k / (p-1)的个数的奇偶性就可以了

如果是偶数 先手打平    如果是奇数 先手胜利

//上面的推导过程 可能还是存在一些问题 见谅= =  有些时候 会不能很好的表述出来。。    最好留言大家一起讨论下啊。。

 1 #include <iostream>
 2 using namespace std;
 3
 4 int main()
 5 {
 6     int x , y , ans;
 7     while( cin >> x >> y )
 8     {
 9         ans = x / (y-1);
10         if( ans&1 )
11             cout << "YES" << endl;
12         else
13             cout << "NO" << endl;
14     }
15     return 0;
16 }

时间: 2024-12-16 15:32:55

hdu--4861--费马小定理&&素数的原根的相关文章

hdu 4704 费马小定理+快速幂

题意就是:做整数拆分,答案是2^(n-1) 由费马小定理可得:2^n % p = 2^[ n % (p-1) ]  % p 当n为超大数时,对其每个数位的数分开来加权计算 当n为整型类型时,用快速幂的方法求解 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; const in

HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)

M斐波那契数列 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input 输入包含多组测试数据: 每组数据占一行,包含3个整数a,

C++实现费马小定理素数测试

#include<iostream> #include<iomanip> #include<cstdlib> #include<ctime> #include<cmath> using namespace std; long long qmod(int a, int b, int p) { long long res = 1; long long term = a%p; while(b) { if(b&1){ res = (res*ter

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

[ACM] hdu 3923 Invoker (Poyla计数,快速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

HDU - 1576(费马小定理求逆元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9278    Accepted Submission(s): 7452 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%99

hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)

题意: 给n(1<n<),求(s1+s2+s3+...+sn)mod(1e9+7).其中si表示n由i个数相加而成的种数,如n=4,则s1=1,s2=3.                         (全题文末) 知识点: 整数n有种和分解方法. 费马小定理:p是质数,若p不能整除a,则 a^(p-1) ≡1(mod p).可利用费马小定理降素数幂. 当m为素数,(m必须是素数才能用费马小定理) a=2时.(a=2只是题中条件,a可以为其他值) mod m =  *      //  k=

HDU 4704 Sum( 费马小定理 )

HDU 4704 Sum( 费马小定理 ) 理解能力果然拙计,,题目看半天没懂什么意思. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define MOD 1000000007 char str[100010]; LL fast_mod( LL a, int b) { LL res = 1; while( b )