QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#780535 | #6179. 最大平方问题 | le0n | 100 ✓ | 2059ms | 25056kb | C++14 | 6.2kb | 2024-11-25 11:27:17 | 2024-11-25 11:27:26 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5, mod = 998244353;
int p;
mt19937 rng(1293128);
map<ll, int> mp;
set<ll> qwq;
int qpow(int x, int y)
{
int ans = 1;
while(y)
{
if(y & 1)
ans = (ll)ans * x % mod;
x = (ll)x * x % mod;
y >>= 1;
}
return ans;
}
int qpow_p(int x, int y)
{
int ans = 1;
while(y)
{
if(y & 1)
ans = (ll)ans * x % p;
x = (ll)x * x % p;
y >>= 1;
}
return ans;
}
void mul_f(vector<int> &A, vector<int> B)
{
int i, j, n, m;
if(A.empty() || B.empty())
{
A.clear();
return ;
}
n = (int)A.size() - 1;
m = (int)B.size() - 1;
A.resize(n + m + 1);
for(i = n + 1; i <= n + m; i++)
A[i] = 0;
for(i = n; i >= 0; i--)
{
for(j = 1; j <= m; j++)
A[i + j] = (A[i + j] + (ll)A[i] * B[j]) % p;
A[i] = (ll)A[i] * B[0] % p;
}
}
void mod_f(vector<int> &A, vector<int> B)
{
int i, j, q, n, m;
while(!B.empty() && !B.back())
B.pop_back();
n = (int)A.size() - 1;
m = (int)B.size() - 1;
if(n < m)
return ;
// printf("MOD %d: \n", p);
// printf("A ");
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
// printf("B ");
// for(auto o: B)
// printf("%d ", o);
// printf("\n");
q = qpow_p(B.back(), p - 2);
for(auto &o: B)
o = (ll)o * q % p;
for(i = n; i >= m; i--)
{
q = p - A[i];
for(j = 1; j <= m; j++)
A[i - j] = (A[i - j] + (ll)q * B[m - j]) % p;
A[i] = 0;
}
while(!A.empty() && !A.back())
A.pop_back();
// printf("res ");
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
}
vector<int> qpow_f(vector<int> A, vector<int> B, int y)
{
vector<int> ans = {1};
// printf("QPOW: \n");
// printf("A ");
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
// printf("B ");
// for(auto o: B)
// printf("%d ", o);
// printf("\n");
while(y)
{
if(y & 1)
{
// printf("!!\n");
mul_f(ans, A);
mod_f(ans, B);
}
mul_f(A, A);
mod_f(A, B);
// printf("tA ");
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
// printf("tres ");
// for(auto o: ans)
// printf("%d ", o);
// printf("\n");
y >>= 1;
}
// printf("res ");
// for(auto o: ans)
// printf("%d ", o);
// printf("\n");
return ans;
}
vector<int> gcd_f(vector<int> A, vector<int> B)
{
int q;
while(!A.empty() && !A.back())
A.pop_back();
while(!B.empty() && !B.back())
B.pop_back();
// printf("GCD %d: \n", p);
// printf("A ");
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
// printf("B ");
// for(auto o: B)
// printf("%d ", o);
// printf("\n");
while(!A.empty())
{
B.swap(A);
if(A.empty())
break;
mod_f(A, B);
}
q = qpow_p(B.back(), p - 2);
for(auto &o: B)
o = (ll)o * q % p;
// printf("res ");
// for(auto o: B)
// printf("%d ", o);
// printf("\n");
return B;
}
vector<int> facto(vector<int> A) // A.back() = 1
{
vector<int> ans, B, C;
int i, j, n, m;
// printf("OOO %d\n", p);
// for(auto o: A)
// printf("%d ", o);
// printf("\n");
if(A.size() == 1)
return {};
if(A.size() == 2)
return {(p - A[0]) % p};
do
{
B.resize(A.size() - 1);
for(auto &o: B)
o = rng() % p;
B = qpow_f(B, A, (p - 1) / 2);
while(B.empty())
B.emplace_back(0);
B[0] = (B[0] + p - 1) % p;
B = gcd_f(A, B);
}
while(B.size() == 1 || B.size() == A.size());
// printf("OKIE\n");
n = (int)A.size() - 1;
m = (int)B.size() - 1;
C.resize(n - m + 1);
for(i = n - m; i >= 0; i--)
{
C[i] = A[i + m];
for(j = 0; j < m; j++)
A[i + j] = (A[i + j] + (ll)(p - C[i]) * B[j]) % p;
A[i + m] = 0;
}
ans = facto(B);
C = facto(C);
for(auto o: C)
ans.emplace_back(o);
return ans;
}
vector<int> fact(vector<int> A)
{
while(!A.empty() && !A.back())
A.pop_back();
if(A.size() <= 1)
return {};
vector<int> B = {0, 1};
B = qpow_f(B, A, p);
while(B.size() < 2)
B.emplace_back(0);
B[1] = (B[1] + p - 1) % p;
return facto(gcd_f(A, B));
}
bool ntp[N];
int prime[N], cnt;
ll res[N], val[N], awa[N];
void sieve(int n)
{
int i, j;
for(i = 2; i <= n; i++)
{
if(!ntp[i])
prime[++cnt] = i;
for(j = 1; j <= cnt && i * prime[j] <= n; j++)
{
ntp[i * prime[j]] = 1;
if(!(i % prime[j]))
break;
}
}
}
int main()
{
// freopen("sqr.in", "r", stdin);
// freopen("sqr.out", "w", stdout);
int n, a, b, c, i, j, k, S, ans = 1;
ll x;
vector<int> tmp;
scanf("%d%d%d%d", &a, &b, &c, &n);
x = (ll)a * n * n + (ll)b * n + c;
S = n;
while((ll)(S + 1) * (S + 1) * (S + 1) <= x)
S++;
while((ll)(S + 1) * (S + 1) <= 2ll * n * a + b)
S++;
sieve(S);
for(i = 0; i <= 2 * n; i++)
awa[i] = (ll)a * i + b;
for(i = 0; i <= n; i++)
val[i] = res[i] = (ll)a * i * i + (ll)b * i + c;
for(i = 1; i <= cnt; i++)
{
p = prime[i];
if(!(a % p))
{
if(b % p)
continue;
for(j = 1; j <= 2 * n; j++)
while(!(awa[j] % p))
awa[j] /= p;
continue;
}
j = (ll)qpow_p(a % p, p - 2) * (p - b % p) % p;
for(k = (j ? j : p); k <= 2 * n; k += p)
while(!(awa[k] % p))
awa[k] /= p;
}
for(i = 1; i <= 2 * n; i++)
if(awa[i] > 1 && awa[i] <= 1e8)
qwq.insert(awa[i]);
for(auto o: qwq)
prime[++cnt] = o;
for(i = 1; i <= cnt; i++)
{
p = prime[i];
if(p > 10)
{
tmp = fact({c % p, b % p, a % p});
for(auto o: tmp)
{
// if(p == 13)
// printf("cry %d\n", o);
// printf("!!%d %d\n", p, o);
for(k = (o ? o : p); k <= n; k += p)
while(!(res[k] % p))
{
res[k] /= p;
mp[p]++;
}
}
}
else
for(j = 0; j < p; j++)
if(!(val[j] % p))
for(k = (j ? j : p); k <= n; k += p)
while(!(res[k] % p))
{
res[k] /= p;
mp[p]++;
}
}
for(i = 1; i <= n; i++)
if(res[i] > 1)
{
// printf("??%d %lld\n", i, res[i]);
S = sqrt(res[i]);
while((ll)(S + 1) * (S + 1) <= res[i])
S++;
while((ll)S * S > res[i])
S--;
if((ll)S * S == res[i])
mp[S] += 2;
else
mp[res[i]]++;
}
for(auto o: mp)
{
// printf("!!%lld %d\n", o.first, o.second);
// assert(check(o.first));
ans = (ll)ans * qpow(o.first % mod, o.second / 2) % mod;
}
ans = (ll)ans * ans % mod;
printf("%d\n", ans);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Pretests
Final Tests
Test #1:
score: 5
Accepted
time: 1ms
memory: 7920kb
input:
17 3 17 14
output:
123798013
result:
ok 1 number(s): "123798013"
Test #2:
score: 5
Accepted
time: 0ms
memory: 7808kb
input:
1 18 0 6
output:
2073600
result:
ok 1 number(s): "2073600"
Test #3:
score: 5
Accepted
time: 1ms
memory: 7808kb
input:
20 6 20 14
output:
315851899
result:
ok 1 number(s): "315851899"
Test #4:
score: 5
Accepted
time: 2ms
memory: 8084kb
input:
81 190 40 125
output:
924770602
result:
ok 1 number(s): "924770602"
Test #5:
score: 5
Accepted
time: 2ms
memory: 7904kb
input:
108 31 110 122
output:
319532761
result:
ok 1 number(s): "319532761"
Test #6:
score: 5
Accepted
time: 13ms
memory: 8288kb
input:
988 194 1412 934
output:
871618879
result:
ok 1 number(s): "871618879"
Test #7:
score: 5
Accepted
time: 15ms
memory: 8168kb
input:
1956 1305 92 1061
output:
681879967
result:
ok 1 number(s): "681879967"
Test #8:
score: 5
Accepted
time: 118ms
memory: 8824kb
input:
75955 165029 149078 5607
output:
739160804
result:
ok 1 number(s): "739160804"
Test #9:
score: 5
Accepted
time: 78ms
memory: 8664kb
input:
3223 4143 3383 4499
output:
139873119
result:
ok 1 number(s): "139873119"
Test #10:
score: 5
Accepted
time: 176ms
memory: 9264kb
input:
9257 3632 1736 9497
output:
158679485
result:
ok 1 number(s): "158679485"
Test #11:
score: 5
Accepted
time: 308ms
memory: 10376kb
input:
13657 8517 9780 16829
output:
499148359
result:
ok 1 number(s): "499148359"
Test #12:
score: 5
Accepted
time: 171ms
memory: 9080kb
input:
152794 105986 145639 8507
output:
432311896
result:
ok 1 number(s): "432311896"
Test #13:
score: 5
Accepted
time: 4ms
memory: 8032kb
input:
2209 13866 42748 227
output:
576767941
result:
ok 1 number(s): "576767941"
Test #14:
score: 5
Accepted
time: 45ms
memory: 8496kb
input:
14279 7290 25915 2265
output:
173729704
result:
ok 1 number(s): "173729704"
Test #15:
score: 5
Accepted
time: 472ms
memory: 13720kb
input:
24703 6569 26356 26534
output:
108700579
result:
ok 1 number(s): "108700579"
Test #16:
score: 5
Accepted
time: 272ms
memory: 9860kb
input:
187348 185285 76358 13718
output:
425402711
result:
ok 1 number(s): "425402711"
Test #17:
score: 5
Accepted
time: 275ms
memory: 10104kb
input:
189507 133399 143282 13930
output:
608644351
result:
ok 1 number(s): "608644351"
Test #18:
score: 5
Accepted
time: 2059ms
memory: 25056kb
input:
102698 162019 98595 137546
output:
388084925
result:
ok 1 number(s): "388084925"
Test #19:
score: 5
Accepted
time: 301ms
memory: 10340kb
input:
152381 90362 151048 15578
output:
413943175
result:
ok 1 number(s): "413943175"
Test #20:
score: 5
Accepted
time: 1039ms
memory: 20200kb
input:
34402 49259 74598 64198
output:
733372582
result:
ok 1 number(s): "733372582"