题意: xqmodp=a ,已知 p,q,a ,求从2000.01.01 00:00:00过了 x <script type="math/tex" id="MathJax-Element-203">x</script>秒后是几年几月几日几时几分几秒。要列出所有的可能情况。如果年份模10等于5或8,则这一年的最后一天会多一秒。(+1s)
求N次剩余,然后模拟出时间…… 不知道为什么,T到死…… 调了调又换了个板子才过……
辣鸡模板……毁我青春……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
typedef long long LL;
int kase = 0;
bool isleap(int yy) {
if (yy % 400 == 0) {
return true;
}
else if (yy % 4 == 0) {
if (yy % 100 != 0)
return true;
}
return false;
}
ll calyear(int yy) {
// 31536000
// 31622400 leap year
// 31536001 leap second
ll res = 31536000;
if (isleap(yy))
res += 86400;
if (yy % 10 == 5 || yy % 10 == 8)
res++;
return res;
}
ll calmonth(int yy, int mm) {
if (mm == 2) {
if (isleap(yy)) {
return 29 * 86400;
}
else
return 28 * 86400;
}
if (mm == 12) {
if (yy % 10 == 5 || yy % 10 == 8) {
return 31 * 86400 + 1;
}
else
return 31 * 86400;
}
if (mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10) {
return 31 * 86400;
}
return 30 * 86400;
}
LL extgcd(LL a, LL b, LL &x, LL &y) {
if (0 == b) {
x = 1;
y = 0;
return a;
} else {
int r = extgcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
}
LL pow_mod(LL x, LL k, LL m) {
LL r = 1 % m;
while (k) {
if (1 & k)r = ((r * x) % m + m) % m;
x = ((x * x) % m + m) % m;
k >>= 1;
}
return r;
}
int g_test(LL g, LL p, vector<LL> &v) {
LL sz = v.size();
for (LL i = 0; i < sz; i++)
if (1 == pow_mod(g, (p - 1) / v[i], p))
return 0;
return 1;
}
LL primitive_rt(LL p) {
LL t = p - 1;
std::vector<LL> v;
for (LL i = 2; i <= t / i; i++)
if (0 == t % i) {
v.push_back(i);
while (0 == t % i)
t /= i;
}
if (1 != t)
v.push_back(t);
LL g = 1;
while (true) {
if (g_test(g, p, v))
return g;
g++;
}
}
LL discrete_log(LL x, LL n, LL m) {
// x^y = n (mod m)
map< LL, LL > rec;
LL s = (LL)sqrt((double)m);
while (s * s <= m)s++;
LL cur = 1;
for (LL i = 0; i < s; i++) {
rec[cur] = i;
cur = ((cur * x) % m + m) % m;
}
LL mul = cur;
cur = 1;
for (LL i = 0; i < s; i++) {
LL more = (n * pow_mod(cur, m - 2, m) % m + m) % m;
if (rec.count(more))
return i * s + rec[more];
cur = ((cur * mul) % m + m) % m;
}
return -1;
}
// x ^ N = a (mod p)
vector<LL> n_residue(LL N, LL a, LL p) {
vector<LL> res;
LL g = primitive_rt(p);
LL m = discrete_log(g, a, p);
if (0 == a) {
res.push_back(0);
return res;
}
if (-1 == m) {
return res;
}
LL A = N, B = p - 1, C = m, x, y;
LL d = extgcd(A, B, x, y);
if (0 != C % d) {
return res;
}
x = x * (C / d) % B;
LL delta = B / d;
for (LL i = 0; i < d; i++) {
x = ((x + delta) % B + B) % B;
res.push_back(pow_mod(g, x, p));
}
sort(res.begin(), res.end());
res.erase(unique(res.begin(), res.end()), res.end());
return res;
}
int main() {
// freopen("1.txt","r",stdin);
int T;
scanf("%d", &T);
getchar();
while (T--) {
ll p, q, a;
scanf("%lld %lld %lld", &p, &q, &a);
// cout<<p<<" "<<q<<" "<<a<<endl;
vector <ll> vec = n_residue(q, a, p);
if (vec.size() == 0) {
printf("Case #%d:\n", ++kase);
printf("Transmission error\n");
continue;
}
printf("Case #%d:\n", ++kase);
for (int i = 0; i < vec.size(); i++) {
int yy = 2000, mm = 1, dd = 1, hour = 0, min = 0, sec = 0;
ll x = vec[i];
while (x >= calyear(yy)) {
x -= calyear(yy);
yy++;
}
while (x >= calmonth(yy, mm)) {
x -= calmonth(yy, mm);
mm++;
}
int cha;
if ((yy % 10 == 5 || yy % 10 == 8) && mm == 12 && dd == 31) {
cha = 86401;
}
else {
cha = 86400;
}
while (x >= cha) {
x -= cha;
dd++;
if ((yy % 10 == 5 || yy % 10 == 8) && mm == 12 && dd == 31) {
cha = 86401;
}
else {
cha = 86400;
}
}
hour = x / 3600;
min = x % 3600 / 60;
sec = x % 60;
if (hour == 24) {
hour = 23;
min = 59;
sec = 60;
}
printf("%04d.%02d.%02d %02d:%02d:%02d\n", yy, mm, dd, hour, min, sec);
}
}
}