题目
ZOJ3785:What day is that day?
求$(1^1+2^2+3^3+…+N^N)%7$
输入
下面$T$行,每行包含一个数字$N (1≤N≤1e9)$
输出
$(1^1+2^2+3^3+…+N^N)%7$
样例输入
2
1
2
样例输出
1
5
分析
一个巨大的数字的巨大的幂的模。
一看就是个费马小定理.用费马定理降幂
回顾费马小定理$ 如果a p互质 那么a^{p-1} ≡ 1 (mod \ \ p)$
这里有$N^N=(7n_1+k_1)^N=(k_1)^N(mod \\ p)$
进一步$(k_1)^N =(k_1)^{(6*n_2+k_2)}(mod \\ p)$
根剧费马小定理有$(k_1)^{(6*n_2)}=1(mod \\ p)$
$(k_1)^N =(k_1)^{(6*n_2+k_2)}=(k_1)^{(k_2)}(mod \\ p) $
费马小定理降幂
上面就是费马小定理降幂推导。
简单讲就是两步,对于幂$p^n\%q$
1. 对底数求模 p%q=m
2. 对指数求模 n%(q-1)=k
最终$p^n\%q=m^k\%q$
继续分析
注意到求出来的$(k_1)^{k_2}%7$,$0<=k_1<7,0<=k_2<6$一共7*6=42种情况
但每42个数后他们得起始数字会发生改变,所以总循环数为7∗42=294
另外
直接暴力打表 找规律完事
代码
# include<iostream>
# include<cmath>
using namespace std;
int s[300];
long long qmi(int a,int k,int q)
{
long long res=1;
while(k)
{
if(k&1)res=(res*a)%q;
a=(long long)a*a%q;
k=k>>1;
}
return res;
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=294;i++)
{
s[i]=(s[i-1]+qmi(i,i,7))%7;
}
while(t--)
{
long long n;
cin>>n;
n=n%294;
cout<<s[n]<<endl;
}
}