ZOJ 3785 What day is that day?

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]);
	}
}

猜你喜欢

转载自www.cnblogs.com/sahdsg/p/10926643.html