QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#780535#6179. 最大平方问题le0n100 ✓2059ms25056kbC++146.2kb2024-11-25 11:27:172024-11-25 11:27:26

Judging History

你现在查看的是最新测评结果

  • [2024-11-25 11:27:26]
  • 评测
  • 测评结果:100
  • 用时:2059ms
  • 内存:25056kb
  • [2024-11-25 11:27:17]
  • 提交

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"