Print the number of integer sequences of length N, A = {A1, A2, A3...., AN} possible where the Sequence A should follow the conditions below:
- All elements in
Ashould be between0andM(inclusive) - XOR of all the elements in
Ais equal toXPrint the number of integer sequence satisfying these conditions modulo998244353. Input Format:N, M , XFunction Description Complete the functioncountIntegerSequencesin the editor.countIntegerSequenceshas the following parameters: N: the length of the sequenceM: the maximum value of the elements in the sequenceX: the XOR value to be achieved Returns int: the number of integer sequences modulo998244353
Constraints
N/A
解法
数位 DP 按位处理。设 f[i][tight][xor_so_far] 但状态太大,所以更优做法:按位独立。每位 b(0..log M):当前位有 K=M+1 个可选值中的"该位为 0/1"的数量,前 N-1 个元素自由(XOR 可任意),最后一个被前面唯一确定。注意 M+1 不一定是 2 的幂,需要按位拆分用经典 digit DP。完整解法用按位的概率/计数:构造长度 N 的序列 XOR=X 等价于:自由选前 N-1 个 ∈[0,M],最后一个 = X XOR(前N-1),但需校验它也在 [0,M]。即答案 = #序列 of length N-1 over [0,M] s.t. their XOR XOR X ∈ [0, M]。可用 DP dp[i][x] = i 个数 XOR 等于 x 的方案数。状态 ≤ N · 2^ceil(log(max(M,X)))。
MOD = 998244353
def countIntegerSequences(N: int, M: int, X: int) -> int:
# bit length needed
L = max(M, X).bit_length()
sz = 1 << L
dp = [0] * sz
dp[0] = 1
for _ in range(N - 1):
ndp = [0] * sz
for x in range(sz):
if dp[x] == 0:
continue
for v in range(M + 1):
ndp[x ^ v] = (ndp[x ^ v] + dp[x]) % MOD
dp = ndp
ans = 0
for x in range(sz):
last = X ^ x
if 0 <= last <= M:
ans = (ans + dp[x]) % MOD
return ans if N >= 1 else (1 if X == 0 else 0)class Solution {
static final int MOD = 998244353;
int countIntegerSequences(int N, int M, int X) {
int L = Math.max(32 - Integer.numberOfLeadingZeros(Math.max(M, X)), 1);
int sz = 1 << L;
long[] dp = new long[sz];
dp[0] = 1;
for (int step = 0; step < N - 1; step++) {
long[] ndp = new long[sz];
for (int x = 0; x < sz; x++) {
if (dp[x] == 0) continue;
for (int v = 0; v <= M; v++) {
ndp[x ^ v] = (ndp[x ^ v] + dp[x]) % MOD;
}
}
dp = ndp;
}
long ans = 0;
for (int x = 0; x < sz; x++) {
int last = X ^ x;
if (last >= 0 && last <= M) ans = (ans + dp[x]) % MOD;
}
return (int) ans;
}
}class Solution {
public:
static const int MOD = 998244353;
int countIntegerSequences(int N, int M, int X) {
int top = max(M, X);
int L = 1;
while ((1 << L) <= top) L++;
int sz = 1 << L;
vector<long long> dp(sz, 0);
dp[0] = 1;
for (int step = 0; step < N - 1; step++) {
vector<long long> ndp(sz, 0);
for (int x = 0; x < sz; x++) {
if (dp[x] == 0) continue;
for (int v = 0; v <= M; v++) {
ndp[x ^ v] = (ndp[x ^ v] + dp[x]) % MOD;
}
}
dp = ndp;
}
long long ans = 0;
for (int x = 0; x < sz; x++) {
int last = X ^ x;
if (last >= 0 && last <= M) ans = (ans + dp[x]) % MOD;
}
return (int) ans;
}
};There are two numbers number A and number B. Your task
Constraints
N/A
Example 1
Input:
A = 7
B = 9
Output:
5
Explanation: Operation 1: B > A so B = 9 - 7 = 2 Operation 2: A > B so A = 7 - 2 = 5 Operation 3: A > B so A = 5 - 2 = 3 Operation 4: A > B so A = 3 - 2 = 1 Operation 5: B > A so B = 2 - 1 = 1 A and B are equal so we stop cost = 5.
解法
观察过程:用大数减去小数若干次直到余数。这其实是欧几里得算法的步数总和。cost(A, B) = A//B + cost(B, A%B),递归直到一方为 0;最终 A==B 即 gcd(A,B),所以 B>0 时一直递归,最后多减一次会等于 0,我们停在 A==B(即上一步前最小值等于 gcd)。实际:累计 A//B 然后递归 (B, A%B),base case 是 A % B == 0 时停止并减少 1(最后一次会过头)。时间复杂度 O(log min(A,B))。
def makeNumbersEqual(A: int, B: int) -> int:
cost = 0
while A and B:
if A < B:
A, B = B, A
cost += A // B
A %= B
if A == 0:
cost -= 1
break
return costclass Solution {
long makeNumbersEqual(long A, long B) {
long cost = 0;
while (A > 0 && B > 0) {
if (A < B) { long t = A; A = B; B = t; }
cost += A / B;
A %= B;
if (A == 0) { cost--; break; }
}
return cost;
}
}class Solution {
public:
long long makeNumbersEqual(long long A, long long B) {
long long cost = 0;
while (A > 0 && B > 0) {
if (A < B) swap(A, B);
cost += A / B;
A %= B;
if (A == 0) { cost--; break; }
}
return cost;
}
};