http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3785
题目
输入n,输出$1^1+2^2+3^3+\cdots+n^n\mod 7$
题解
按照同余系,把$i^i$分到$i$的7个同余系中,得
\[\begin{array}{ccccccc}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}\\\vdots\\1^{1+7k}&2^{2+7k}&3^{3+7k}&\cdots\\\end{array}\]
套5个等比数列求和公式
$\frac{i-i^{i+7k+7}}{1-i^7}\equiv ans \pmod{7}$
验证发现$i=2..6$都有逆,乘逆即可
AC代码:
#include <bits/stdc++.h>
#define REP(r,x,y) for(register int r=(x); r<(y); r++)
using namespace std;
typedef long long ll;
int read() {
int ret = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') { ret = ret * 10 + c - '0'; c = getchar(); }
return ret * f;
}
inline void read(int& x) {
x = read();
}
const int mod = 7;
inline int qpow(int a, ll b) {
int ans=1;
for (; b; b >>= 1) {
if (b & 1) ans = (ans * a) % 7;
a = (a * a) % 7;
}
return ans;
}
int cnts[7];
const int ni[] = { 0,0,6,3,2,5,4 };
const char w[][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
int main() {
int t; read(t);
while (0 < t--) {
int n; read(n);
cnts[0] = n / 7;
REP(i, 1, 7) cnts[i] = cnts[0];
int k = n % 7;
REP(i, 1, 7) {
if (i > k) break;
cnts[i]++;
}
int ans = cnts[1];
REP(i, 2, 7) {
if (cnts[i] == 0)continue;
int k = qpow(i, i) - qpow(i, (ll)7*cnts[i]+i);
k *= ni[i];
k %= 7;
ans += k;
}
ans %= 7; ans--; if (ans < 0) ans += 7;
puts(w[ans]);
}
}