费马小定理:假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
同余证法:
任意取一个质数,比如13。考虑从1到12的一系列整数1,2,3,4,5,6,7,8,9,10,11,12,给这些数都乘上一个与13互质的数,比如3,得到3,6,9,12,15,18,21,24,27,30,33,36。对于模13来说,这些数同余于3,6,9,12,2,5,8,11,1,4,7,10。这些余数实际上就是原来的1,2,3,4,5,6,7,8,9,10,11,12,只是顺序不同而已。
把1,2,3,…,12统统乘起来,乘积就是12的阶乘12!。把3,6,9,…,36也统统乘起来,并且提出公因子3,乘积就是312×12!。对于模13来说,这两个乘积都同余于1,2,3,…,12系列,尽管顺序不是一一对应,即312×12!≡12!mod 13。两边同时除以12!得312≡1 mod 13。如果用p代替13,用x代替3,就得到费马小定理xp-1≡1 mod p。
以zoj3785(http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3785)为例:
It's Saturday today, what day is it after 1^1 + 2^2 + 3^3 + ... + N^N days? (1 <= N <= 1000000000).
对于
1^1 2^2 3^3 4^4 5^5 6^6 7^7
8^8 9^9 10^10 11^11 12^12 13^13 14^14
15^15 16^16 17^17 18^18 19^19 20^20 21^21
22^22 23^23 24^24 25^25 26^26 27^27 28^28
29^29 30^30 31^31 32^32 33^33 34^34 35^35
36^36 37^37 38^38 39^39 40^40 41^41 42^42
43^43 44^44 45^45 46^46 47^47 48^48 49^49
都对7取模后
1^1 2^2 3^3 4^4 5^5 6^6 0^7
1^8 2^9 3^10 4^11 5^12 6^13 0^14
1^15 2^16 3^17 4^18 5^19 6^20 0^21
1^22 2^23 3^24 4^25 5^26 6^27 0^28
1^29 2^30 3^31 4^32 5^33 6^34 0^35
1^36 2^37 3^38 4^39 5^40 6^41 0^42
1^43 2^44 3^45 4^46 5^47 6^48 0^49
根据费马小定理x6≡1(mod 7)可得
1^1 2^2 3^3 4^4 5^5 6^6 0
1^2 2^3 3^4 4^5 5^6 6^1 0
1^3 2^4 3^5 4^6 5^1 6^2 0
1^4 2^5 3^6 4^1 5^2 6^3 0
1^5 2^6 3^1 4^2 5^3 6^4 0
1^6 2^1 3^2 4^3 5^4 6^5 0
1^1 2^2 3^3 4^4 5^5 6^6 0
每六行一个循环,循环节长度为42
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<vector>
#include<math.h>
#include<stack>
using namespace std;
const int MAX = 1000+10;
const double eps = 1e-10;
const double PI = acos(-1.0);
long long n;
int t;
int s[50];
int main()
{
for(int i=1; i<=44; i++)
{
int flag=i%7;
int ans=1;
for(int j=1; j<=i; j++)
ans=(ans*flag)%7;
s[i]=ans;
}
for(int i=1; i<=44; i++)
s[i]+=s[i-1];
scanf("%d", &t);
long long ans;
while(t--)
{
scanf("%lld", &n);
ans=(n/42%7*(s[42]%7)%7+s[n%42]%7)%7;
ans = (ans+6)%7;
if(ans==1)printf("Monday\n");
else if(ans==2)printf("Tuesday\n");
else if(ans==3)printf("Wednesday\n");
else if(ans==4)printf("Thursday\n");
else if(ans==5)printf("Friday\n");
else if(ans==6)printf("Saturday\n");
else printf("Sunday\n");
}
return 0;
}