http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3785
题目
输入n,输出$1^1+2^2+3^3+\cdots+n^n\mod 7$
题解
按照同余系,把$i^i$分到7个同余系中,得
\[\begin{array}{ccccccc}1^1&2^2&3^3&4^4&5^5&6^6&7^7\\1^8&2^9&3^{10}&4^{11}&5^{12}&6^{13}&7^{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]); } }