QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#291086#4056. 进制转换MoRanSky100 ✓883ms198648kbC++234.3kb2023-12-26 04:47:472023-12-26 04:47:47

Judging History

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

  • [2023-12-26 04:47:47]
  • 评测
  • 测评结果:100
  • 用时:883ms
  • 内存:198648kb
  • [2023-12-26 04:47:47]
  • 提交

answer

// Skyqwq
#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int X = 21, Y = 13, P = 998244353, O = 998244352;

typedef vector<int> Poly;

#define pb push_back

const int N = 5000000 + 5, G = 3;

int A[N], rev[N], mod;
int lim = 1, len = 0, W[24][N];

int inline power(int a, int b, int Mod = P) {
	int res = 1;
	while (b) {
		if (b & 1) res = (LL)res * a % Mod;
		a = (LL)a * a % Mod;
		b >>= 1;
	}
	return res;
}
int Gi = power(G, P - 2, P), inv2 = power(2, P - 2, P);


void inline NTT(int c[], int lim, int o) {
	for (int i = 0; i < lim; i++)
		if (i < rev[i]) swap(c[i], c[rev[i]]);
	for (int k = 1, t = 0; k < lim; k <<= 1, t++) {
		for (int i = 0; i < lim; i += (k << 1)) {
			for (int j = 0; j < k; j++) {
				int u = c[i + j], v = (LL)c[i + k + j] * W[t][j] % P;
				c[i + j] = u + v >= P ? u + v - P : u + v;
				c[i + j + k] = u - v < 0 ? u - v + P : u - v; 
			}
		}
	}
	if (o == -1) {
		reverse(c + 1, c + lim);
		int inv = power(lim, P - 2, P);
		for (int i = 0; i < lim; i++)
			c[i] = (LL)c[i] * inv % P;
	}
}

void inline setN(int n) {
	lim = 1, len = 0;
	while (lim < n) lim <<= 1, len++;
	for (int i = 0; i < lim; i++)
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
}

Poly inline NTT(Poly a, int o) {
	int n = a.size();
	for (int i = 0; i < n; i++) A[i] = a[i];
	NTT(A, lim, o);
	a.clear();
	for (int i = 0; i < lim; i++) a.push_back(A[i]), A[i] = 0;
	return a;
}


Poly inline mul (Poly a, Poly b, int newn = -1) {
	if (newn == -1) newn = a.size() + b.size() - 1;
	setN(a.size() + b.size() - 1);
	Poly c = NTT(a, 1), d = NTT(b, 1);
	for (int i = 0; i < lim; i++) c[i] = (LL)c[i] * d[i] % P;
	d = NTT(c, -1); d.resize(newn);
	return d;
}
// 用到的最大的 n
void inline init(int n) {
	setN(2 * n);
	for (int k = 1, t = 0; k < lim; k <<= 1, t++) {
		int wn = power(G, (P - 1) / (k << 1));
		W[t][0] = 1;
		for (int j = 1; j < k; j++) W[t][j] = (LL)W[t][j - 1] * wn % P;
	}
}

int x, y, z, U, V;

int cnt[20000000];

int v1[20000000];

LL n;

int ans;

void inline add(int &x, int y) {
	x += y;
	if (x >= P) x -= P;
}

int tp(LL x) {
	int c = 0;
	while (x) c += x % 3, x /= 3;
	return c;
}

void inline del(int &x, int y) {
	x -= y;
	if (x < 0) x += P;
}

void inline work(LL l, LL r) {
	for (LL i = l; i <= r; i++) {
		add(ans, 1ll * power(x, i % O) * power(y, __builtin_popcountll(i)) % P * power(z, tp(i)) % P);
	}
}

int main() {
    U = 1 << X;
    V = 1;
    ans = P - 1;
    for (int i = 0; i < Y; i++) V *= 3;
    init(V);
    read(n), read(x), read(y), read(z);
	Poly a(U + 1, 0), b(V, 0);
	int val = 1;
	cnt[0] = 1;
	for (int i = 0; i < U; i++) {
		cnt[i] = 1ll * cnt[i >> 1] * ((i & 1) ? y : 1) % P;
		a[U - i] = 1ll * cnt[i] * val % P;
		val = 1ll * val * x % P;
	}
	cnt[0] = 1;
	int z2 = 1ll * z * z % P;
	for (int i = 0; i < V; i++) {
		cnt[i] = cnt[i / 3];
		if (i % 3 == 2) cnt[i] = 1ll * cnt[i] * z2 % P;
		else if (i % 3 == 1) cnt[i] = 1ll * cnt[i] * z % P;
		b[i] = cnt[i];
	}
	Poly c = mul(a, b);

	int kx = power(x, U);

	int p1 = 0;
	int vc = 1;

	cnt[0] = v1[0] = 1;

	for (LL l = 0; l <= n; ) {
		int m1 = l / U, m2 = l / V;
		cnt[m1] = 1ll * cnt[m1 >> 1] * ((m1 & 1) ? y : 1) % P;
		v1[m2] = v1[m2 / 3];
		if (m2 % 3 == 2) v1[m2] = 1ll * v1[m2] * z2 % P;
		else if (m2 % 3 == 1) v1[m2] = 1ll * v1[m2] * z % P;
		if (p1 < m1) ++p1, vc = 1ll * vc * kx % P;
		assert(p1 == m1);
		LL n1 = (m1 + 1ll) * U - 1, n2 = (m2 + 1ll) * V - 1;
		LL nx = min(n1, n2);
		if (nx > n) {
			work(l, n);
			break;
		}
		
		LL dt = m1 * U - m2 * V + U;
		if (dt >= 0 && dt < c.size())
			add(ans, 1ll * c[dt] * vc % P * cnt[m1] % P * v1[m2] % P);
		else assert(false);		
		l = nx + 1;
		
	}
	printf("%d\n", ans);
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 5
Accepted
time: 543ms
memory: 195816kb

input:

9134097 778012792 263448561 839843856

output:

887680205

result:

ok 1 number(s): "887680205"

Test #2:

score: 5
Accepted
time: 449ms
memory: 194004kb

input:

9896386 2948513 263418583 271155379

output:

853292631

result:

ok 1 number(s): "853292631"

Test #3:

score: 5
Accepted
time: 536ms
memory: 195652kb

input:

9150910 827328107 842171962 39947937

output:

534921610

result:

ok 1 number(s): "534921610"

Test #4:

score: 5
Accepted
time: 826ms
memory: 194716kb

input:

9586674634211 1 1 58301262

output:

13306748

result:

ok 1 number(s): "13306748"

Test #5:

score: 5
Accepted
time: 782ms
memory: 196660kb

input:

9774917720998 1 1 609549524

output:

825025220

result:

ok 1 number(s): "825025220"

Test #6:

score: 5
Accepted
time: 883ms
memory: 196084kb

input:

9765239207265 422503033 1 719749187

output:

993518920

result:

ok 1 number(s): "993518920"

Test #7:

score: 5
Accepted
time: 802ms
memory: 198648kb

input:

9732354736444 277693641 1 501293609

output:

77844778

result:

ok 1 number(s): "77844778"

Test #8:

score: 5
Accepted
time: 624ms
memory: 195928kb

input:

9004409828 377918953 449219487 26422407

output:

110868569

result:

ok 1 number(s): "110868569"

Test #9:

score: 5
Accepted
time: 428ms
memory: 194032kb

input:

9579878149 820453354 218842704 133154415

output:

727248713

result:

ok 1 number(s): "727248713"

Test #10:

score: 5
Accepted
time: 542ms
memory: 194492kb

input:

9475807443 305433821 391589421 170059051

output:

372839725

result:

ok 1 number(s): "372839725"

Test #11:

score: 5
Accepted
time: 661ms
memory: 196572kb

input:

484758270277 372146623 410538257 35340632

output:

575284574

result:

ok 1 number(s): "575284574"

Test #12:

score: 5
Accepted
time: 426ms
memory: 195784kb

input:

473458173541 864158404 220259603 529747800

output:

610487662

result:

ok 1 number(s): "610487662"

Test #13:

score: 5
Accepted
time: 515ms
memory: 195292kb

input:

459992983903 359742981 983942229 552405867

output:

81366483

result:

ok 1 number(s): "81366483"

Test #14:

score: 5
Accepted
time: 503ms
memory: 196324kb

input:

462331701308 665849375 563297194 141092054

output:

774987426

result:

ok 1 number(s): "774987426"

Test #15:

score: 5
Accepted
time: 727ms
memory: 195928kb

input:

9061635042931 746632077 302662913 559990819

output:

274721229

result:

ok 1 number(s): "274721229"

Test #16:

score: 5
Accepted
time: 825ms
memory: 194372kb

input:

9653325901537 559549569 638292572 474780356

output:

418906016

result:

ok 1 number(s): "418906016"

Test #17:

score: 5
Accepted
time: 861ms
memory: 192996kb

input:

9640271229478 619740479 644097590 907038757

output:

936646026

result:

ok 1 number(s): "936646026"

Test #18:

score: 5
Accepted
time: 773ms
memory: 194988kb

input:

9781711161203 988850684 154464719 995932763

output:

166841144

result:

ok 1 number(s): "166841144"

Test #19:

score: 5
Accepted
time: 704ms
memory: 195736kb

input:

9156325004698 915375188 316066096 217969045

output:

306877956

result:

ok 1 number(s): "306877956"

Test #20:

score: 5
Accepted
time: 766ms
memory: 195164kb

input:

9042535293051 906265264 156788435 622201740

output:

397975092

result:

ok 1 number(s): "397975092"