QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#215522 | #4801. The Pool | ucup-team1209 | WA | 18ms | 3824kb | C++14 | 5.0kb | 2023-10-15 11:25:57 | 2023-10-15 11:25:57 |
Judging History
answer
#include <bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
using ll = long long ;
using i128 = __int128;
using f64 = long double;
cs int Mod = 998244353;
ll p;
f64 invp;
void setmod(ll x) {
p = x, invp = (f64) 1 / x;
}
ll mul(ll a, ll b) {
ll z = a * invp * b + 0.5;
ll res = a * b - z * p;
return res + (res >> 63 & p);
}
ll pow(ll a, ll x, ll res = 1) {
for(;x;x >>= 1, a = mul(a, a))
if(x & 1) res = mul(res, a);
return res;
}
bool checkprime(ll p) {
if(p == 1) return 0;
setmod(p);
ll d = __builtin_ctzll(p - 1), s = (p - 1) >> d;
for(ll a : {2, 3, 5, 7, 11, 13, 82, 373}) {
if(a % p == 0)
continue;
ll x = pow(a, s), y;
for(int i = 0;i < d;++i, x = y) {
y = mul(x, x);
if(y == 1 && x != 1 && x != p - 1)
return 0;
}
if(x != 1) return 0;
}
return 1;
}
ll rho(ll n) {
if(!(n & 1)) return 2;
static std::mt19937_64 gen((size_t)"hehezhou");
ll c = gen() % (n - 1) + 1, y = gen() % (n - 1) + 1;
auto f = [&](ll o) {
o = mul(o, o) + c;
return o >= n ? o - n : o;
};
setmod(p);
for(int l = 1;;l <<= 1) {
ll x = y, g = 1;
for(int i = 0;i < l;++i) y = f(y);
const int d = 512;
for(int i = 0;i < l;i += d) {
ll sy = y;
for(int j = 0;j < std::min(d, l - i);++j) {
y = f(y), g = mul(g, (y - x + n));
}
g = std::__gcd(n, g);
if(g == 1)
continue;
if(g == n)
for(g = 1, y = sy;g == 1;)
y = f(y), g = std::__gcd(n, y - x + n);
return g;
}
}
}
std::vector<ll> factor(ll x) {
std::queue<ll> q; q.push(x);
std::vector<ll> res;
for(;q.size();) {
ll x = q.front(); q.pop();
if(x == 1) continue;
if(checkprime(x)) {
res.push_back(x);
continue;
}
ll y = rho(x);
q.push(y), q.push(x / y);
}
sort(res.begin(), res.end());
return res;
}
struct cp {
ll x, y;
cp(ll x = 0, ll y = 0) : x(x), y(y) {}
cp operator + (cs cp &b) { return cp(x + b.x, y + b.y); }
cp operator - (cs cp &b) { return cp(x - b.x, y - b.y); }
cp operator * (cs cp &b) { return cp(x * b.x - y * b.y, x * b.y + y * b.x); }
cp conj() { return cp(x, -y); }
i128 norm() { return x * x + y * y; }
};
mt19937_64 rnd(223);
ll R(f64 x) { return round(x); }
cp operator / (cs cp & a, cs cp & b) {
complex <f64> A(a.x, a.y), B(b.x, b.y), C = A / B;
// cout << C.real() << ' ' << C.imag() << endl;
return cp(R(C.real()), R(C.imag()));
}
cp mod(cp a, cp b) {
cp c = a / b;
return a - b * c;
}
cp gcd(cp a, cp b) {
if(b.norm() == 0) return a;
cp c = mod(a, b);
// cout << (ll) a.norm() << ' ' << (ll) b.norm() << ' ' << (ll) c.norm() << ' ' << a.x << ' ' << a.y << ' ' << b.x << ' ' <<b.y << ' ' << c.x << ' ' << c.y << endl;
assert(c.norm() < b.norm());
return gcd(b, c);
}
ll ksm(ll a, ll b, ll p) {
ll c = 1;
for(; b; b >>= 1, a = (i128) a * a % p)
if(b & 1) c = (i128) c * a % p;
return c;
}
cp get(ll p) {
cp c(1, 0);
while(1) {
ll x = rnd() % p;
ll y = ksm(x, (p - 1) / 4, p);
if(((i128) y * y + 1) % p == 0) {
c = cp(y, 1); break;
}
}
c = gcd(c, cp(p, 0));
return c;
}
ll calc(ll x, ll y, ll n, ll m) {
ll d = __gcd(x, y);
if((i128) d * m % n) return 0;
i128 all = (x + (i128) y * m / n) * (y + (i128) x * m / n);
// cout << (ll) all << endl;
all -= ((i128) x * m / n - y) * ((i128) y * m / n - x);
// cout << (ll) all << endl;
assert(all % 2 == 0);
i128 e = x + y - d;
// cout << (ll) e << endl;
e = e + (i128) e * m / n;
all = all / 2 - e;
// cout << x << ' ' << y << ' ' << n<< ' ' << m << ' ' << (ll)all % Mod << endl;
return all % Mod;
}
void Main() {
ll n, m;
cin >> n >> m;
if(n > m) swap(n, m);
vector <ll> pr = factor (n);
map <ll, int> mp;
for(ll x : pr) ++ mp[x];
vector <cp> ans = {{1, 0}, {0, 1}};
for(auto [x, y] : mp) {
// cout << x << ' ' << y << endl;
if(x % 4 == 1) {
cp ab = get(x), ba = ab.conj();
vector <cp> nxt;
for(int i = 0; i <= y; i++) {
cp cur(1, 0);
for(int j = 0; j < i; j++)
cur = cur * ab;
for(int j = i; j < y * 2; j++)
cur = cur * ba;
// cout << "FFFFGGGG " << cur.x << ' ' << cur.y << endl;
for(auto c : ans)
nxt.pb(c * cur);
}
swap(nxt, ans);
} else {
for(int t = 0; t < y; t++)
for(auto & c : ans)
c = c * x;
}
}
ll sum = (i128) n * m % Mod;
for(auto c : ans) {
ll x = c.x, y = c.y;
x = abs(x), y = abs(y);
// cout << "Case " << x << ' ' << y << endl;
if(x && y) sum = (sum + calc(x, y, n, m)) % Mod;
}
if(n != m) sum = sum * 2 % Mod;
cout << sum << '\n';
}
int main() {
#ifdef zqj
freopen("1.in", "r", stdin);
#endif
int T;
cin >> T;
while(T--) Main();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3824kb
input:
5 5 5 2 3 5 10 2197525579 1145141 91 65
output:
51 12 228 438744975 34722
result:
ok 5 number(s): "51 12 228 438744975 34722"
Test #2:
score: -100
Wrong Answer
time: 18ms
memory: 3584kb
input:
10000 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 1 60 1 6...
output:
1 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 128 130 132 134 136 138 140 142 144 146 148 150 152 154 156 158 160 162 164 166 168 170 172 174 176 1...
result:
wrong answer 6465th numbers differ - expected: '36729', found: '28591'