QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#468702 | #3799. It's Surely Complex | PetroTarnavskyi | TL | 2ms | 5892kb | C++23 | 6.5kb | 2024-07-08 23:08:45 | 2024-07-08 23:08:46 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef __float128 db;
typedef unsigned long long ULL;
int p;
ULL mod = 9223372036737335297;
const int LEN = 1 << 20;
ULL add(ULL a, ULL b)
{
return a + b < mod ? a + b : a + b - mod;
}
ULL sub(ULL a, ULL b)
{
return a >= b ? a - b : a + mod - b;
}
ULL mult(ULL a, ULL b)
{
return (__int128)a * b % mod;
}
ULL binpow(ULL a, ULL n)
{
ULL res = 1;
while (n)
{
if (n & 1)
res = mult(res, a);
a = mult(a, a);
n /= 2;
}
return res;
}
const ULL GEN = binpow(3, (mod - 1) / LEN);
const ULL IGEN = binpow(GEN, mod - 2);
void fft(vector<ULL>& a, bool inv)
{
int lg = __builtin_ctz(SZ(a));
FOR(i, 0, SZ(a))
{
int k = 0;
FOR(j, 0, lg)
k |= ((i >> j) & 1) << (lg - j - 1);
if (i < k)
swap(a[i], a[k]);
}
for (int len = 2; len <= SZ(a); len *= 2)
{
ULL ml = binpow(inv ? IGEN : GEN, LEN / len);
for (int i = 0; i < SZ(a); i += len)
{
ULL pw = 1;
FOR(j, 0, len / 2)
{
ULL v = a[i + j];
ULL u = mult(a[i + j + len / 2], pw);
a[i + j] = add(v, u);
a[i + j + len / 2] = sub(v, u);
pw = mult(pw, ml);
}
}
}
if (inv)
{
ULL m = binpow(SZ(a), mod - 2);
FOR(i, 0, SZ(a))
a[i] = mult(a[i], m);
}
}
VI mult(VI a, VI b)
{
int sum = SZ(a) + SZ(b) - 1;
if(max(SZ(a), SZ(b)) < 20)
{
vector<LL> res(sum);
FOR(i, 0, SZ(a))
FOR(j, 0, SZ(b))
res[i + j] += (LL)a[i] * b[j];
FOR(i, 0, sum)
res[i] %= p;
return VI(ALL(res));
}
vector<ULL> A(ALL(a)), B(ALL(b));
int sz = 0;
while ((1 << sz) < sum)
sz++;
A.resize(1 << sz);
B.resize(1 << sz);
fft(A, false);
fft(B, false);
FOR(i, 0, SZ(A))
A[i] = mult(A[i], B[i]);
fft(A, true);
VI res(sum);
FOR(i, 0, sum)
res[i] = A[i] % p;
return res;
}
int sub(int a, int b)
{
return a - b >= 0 ? a - b : a - b + p;
}
void updAdd(int& a, int b)
{
a += b;
if (a >= p)
a -= p;
}
void updSub(int& a, int b)
{
a -= b;
if (a < 0)
a += p;
}
int mult(int a, int b)
{
return (LL)a * b % p;
}
int binpow(int a, int n)
{
int res = 1;
while (n)
{
if (n & 1)
res = mult(res, a);
a = mult(a, a);
n /= 2;
}
return res;
}
VI inverse(const VI& a, int k)
{
//assert(SZ(a) == k && a[0] != 0);
if (k == 1)
return {binpow(a[0], p - 2)};
VI ra = a;
FOR(i, 0, SZ(ra))
if (i & 1)
ra[i] = sub(0, ra[i]);
int nk = (k + 1) / 2;
VI t = mult(a, ra);
t.resize(k);
VI nt(nk);
FOR(i, 0, nk)
nt[i] = t[2 * i];
nt = inverse(nt, nk);
RFOR(i, nk, 1)
{
t[2 * i] = nt[i];
t[i] = 0;
}
VI res = mult(ra, t);
res.resize(k);
return res;
}
inline void removeLeadingZeros(VI& a)
{
while (SZ(a) > 0 && a.back() == 0)
a.pop_back();
}
pair<VI, VI> modulo(VI a, VI b)
{
removeLeadingZeros(a);
removeLeadingZeros(b);
int n = SZ(a), m = SZ(b);
if (m > n)
return MP(VI{}, a);
//assert(n != 0 && m != 0);
reverse(ALL(a));
reverse(ALL(b));
VI d = b;
d.resize(n - m + 1);
d = mult(a, inverse(d, n - m + 1));
d.resize(n - m + 1);
reverse(ALL(a));
reverse(ALL(b));
reverse(ALL(d));
VI res = mult(b, d);
res.resize(SZ(a));
FOR(i, 0, SZ(a))
res[i] = sub(a[i], res[i]);
removeLeadingZeros(d);
removeLeadingZeros(res);
return MP(d, res);
}
int x[LEN];
VI P[2 * LEN];
void build(int v, int tl, int tr)
{
if (tl + 1 == tr)
{
P[v] = {sub(0, x[tl]), 1};
return;
}
int tm = (tl + tr) / 2;
build(2 * v + 1, tl, tm);
build(2 * v + 2, tm, tr);
P[v] = mult(P[2 * v + 1], P[2 * v + 2]);
}
int Ans[LEN];
void solve(int v, int tl, int tr, const VI& q)
{
if (tl + 1 == tr)
{
Ans[tl] = SZ(q) ? q[0] : 0;
return;
}
int tm = (tl + tr) / 2;
solve(2 * v + 1, tl, tm, modulo(q, P[2 * v + 1]).S);
solve(2 * v + 2, tm, tr, modulo(q, P[2 * v + 2]).S);
}
complex<LL> mult(complex<LL> a, complex<LL> b)
{
a *= b;
a = {(a.real() % p + p) % p, (a.imag() % p + p) % p};
return a;
}
complex<LL> binpow(complex<LL> a, LL n)
{
complex<LL> res = {1, 0};
while (n)
{
if (n & 1)
res = mult(res, a);
a = mult(a, a);
n /= 2;
}
return res;
}
pair<VI, VI> splitRealImag(int k, const VI& a)
{
assert(SZ(a) == k + 1);
VI resReal(k + 1), resImag(k + 1);
FOR(i, 0, k + 1)
{
int r = (k - i) % 4;
if (r == 0)
updAdd(resReal[i], a[i]);
else if (r == 1)
updAdd(resImag[i], a[i]);
else if (r == 2)
updSub(resReal[i], a[i]);
else
updSub(resImag[i], a[i]);
}
return {resReal, resImag};
}
vector<complex<LL>> f(int k)
{
FOR(i, 0, k)
x[i] = sub(0, i);
build(0, 0, k);
//cerr << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
auto [polReal, polImag] = splitRealImag(k, P[0]);
//cerr << polReal[0] << ' ' << polReal[1] << '\n';
//cerr << polImag[0] << ' ' << polImag[1] << '\n';
FOR(i, 0, p)
x[i] = i;
build(0, 0, p);
//cerr << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
solve(0, 0, p, polReal);//modulo(polReal, P[0]).S);
VI ysReal(p);
FOR(i, 0, p)
ysReal[i] = Ans[i];
//cerr << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
solve(0, 0, p, polImag);//modulo(polImag, P[0]).S);
VI ysImag(p);
FOR(i, 0, p)
ysImag[i] = Ans[i];
//cerr << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
vector<complex<LL>> res(p);
FOR(j, 0, p)
res[j] = {ysReal[j], ysImag[j]};
return res;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
LL n;
cin >> p >> n;
vector<complex<LL>> f1 = f(p);
vector<complex<LL>> f2 = f(n % p + 1);
//cerr << "F1\n";
//for (auto c : f1)
// cerr << c.real() << ' ' << c.imag() << '\n';
//
//cerr << "F2\n";
//cerr << SZ(f2) << '\n';
//for (auto c : f2)
// cerr << c.real() << ' ' << c.imag() << '\n';
complex<LL> ans = {1, 0};
FOR(j, 1, p)
ans = mult(ans, complex<LL>(0, j));
ans = binpow(ans, n / p);
FOR(j, 1, n % p + 1)
{
ans = mult(ans, complex<LL>(0, j));
}
ans = binpow(ans, n / p + 1);
FOR(xi, 1, p)
{
if (xi > n)
break;
ans = mult(ans, binpow(mult(binpow(f1[xi], n / p), f2[xi]), (n - xi) / p + 1));
}
cout << ans.real() << " " << ans.imag() << "\n";
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5684kb
input:
2 1
output:
1 1
result:
ok single line: '1 1'
Test #2:
score: 0
Accepted
time: 0ms
memory: 5624kb
input:
2 2
output:
1 1
result:
ok single line: '1 1'
Test #3:
score: 0
Accepted
time: 2ms
memory: 5892kb
input:
2 3
output:
0 0
result:
ok single line: '0 0'
Test #4:
score: 0
Accepted
time: 2ms
memory: 5600kb
input:
2 4
output:
0 0
result:
ok single line: '0 0'
Test #5:
score: 0
Accepted
time: 2ms
memory: 5604kb
input:
3 1
output:
2 1
result:
ok single line: '2 1'
Test #6:
score: 0
Accepted
time: 2ms
memory: 5884kb
input:
3 2
output:
2 0
result:
ok single line: '2 0'
Test #7:
score: 0
Accepted
time: 2ms
memory: 5692kb
input:
3 3
output:
1 0
result:
ok single line: '1 0'
Test #8:
score: 0
Accepted
time: 2ms
memory: 5600kb
input:
3 4
output:
1 1
result:
ok single line: '1 1'
Test #9:
score: 0
Accepted
time: 2ms
memory: 5596kb
input:
3 5
output:
1 0
result:
ok single line: '1 0'
Test #10:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
3 6
output:
1 0
result:
ok single line: '1 0'
Test #11:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
5 1
output:
4 1
result:
ok single line: '4 1'
Test #12:
score: 0
Accepted
time: 2ms
memory: 5668kb
input:
5 2
output:
0 0
result:
ok single line: '0 0'
Test #13:
score: 0
Accepted
time: 0ms
memory: 5884kb
input:
5 3
output:
0 0
result:
ok single line: '0 0'
Test #14:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
5 4
output:
0 0
result:
ok single line: '0 0'
Test #15:
score: 0
Accepted
time: 2ms
memory: 5600kb
input:
5 5
output:
0 0
result:
ok single line: '0 0'
Test #16:
score: 0
Accepted
time: 2ms
memory: 5600kb
input:
5 6
output:
0 0
result:
ok single line: '0 0'
Test #17:
score: 0
Accepted
time: 2ms
memory: 5596kb
input:
5 7
output:
0 0
result:
ok single line: '0 0'
Test #18:
score: 0
Accepted
time: 2ms
memory: 5876kb
input:
5 8
output:
0 0
result:
ok single line: '0 0'
Test #19:
score: 0
Accepted
time: 0ms
memory: 5672kb
input:
5 9
output:
0 0
result:
ok single line: '0 0'
Test #20:
score: 0
Accepted
time: 0ms
memory: 5600kb
input:
5 10
output:
0 0
result:
ok single line: '0 0'
Test #21:
score: 0
Accepted
time: 2ms
memory: 5596kb
input:
7 1
output:
6 1
result:
ok single line: '6 1'
Test #22:
score: 0
Accepted
time: 2ms
memory: 5680kb
input:
7 2
output:
3 0
result:
ok single line: '3 0'
Test #23:
score: 0
Accepted
time: 0ms
memory: 5600kb
input:
7 3
output:
2 5
result:
ok single line: '2 5'
Test #24:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
7 4
output:
1 0
result:
ok single line: '1 0'
Test #25:
score: 0
Accepted
time: 0ms
memory: 5664kb
input:
7 5
output:
5 2
result:
ok single line: '5 2'
Test #26:
score: 0
Accepted
time: 2ms
memory: 5552kb
input:
7 6
output:
6 0
result:
ok single line: '6 0'
Test #27:
score: 0
Accepted
time: 0ms
memory: 5812kb
input:
7 7
output:
1 0
result:
ok single line: '1 0'
Test #28:
score: 0
Accepted
time: 2ms
memory: 5616kb
input:
7 8
output:
4 4
result:
ok single line: '4 4'
Test #29:
score: 0
Accepted
time: 2ms
memory: 5848kb
input:
7 9
output:
4 0
result:
ok single line: '4 0'
Test #30:
score: 0
Accepted
time: 0ms
memory: 5816kb
input:
7 10
output:
2 2
result:
ok single line: '2 2'
Test #31:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
7 11
output:
1 0
result:
ok single line: '1 0'
Test #32:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
7 12
output:
4 4
result:
ok single line: '4 4'
Test #33:
score: 0
Accepted
time: 2ms
memory: 5684kb
input:
7 13
output:
1 0
result:
ok single line: '1 0'
Test #34:
score: 0
Accepted
time: 0ms
memory: 5892kb
input:
7 14
output:
1 0
result:
ok single line: '1 0'
Test #35:
score: 0
Accepted
time: 2ms
memory: 5608kb
input:
2 1000000000000000000
output:
0 0
result:
ok single line: '0 0'
Test #36:
score: 0
Accepted
time: 0ms
memory: 5844kb
input:
3 1000000000000000000
output:
1 1
result:
ok single line: '1 1'
Test #37:
score: -100
Time Limit Exceeded
input:
499979 1000000000000000000