問題描述
你得到一個長度為 $n$ 的整數陣列
從左到右計算每個長度為 $k$ 的視窗 or 完的結果
然後將這些最小值做 xor 運算(逐一累積後再輸出結果)
練習題
完整程式碼
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// 主邏輯:計算所有長度 k 的滑動視窗的 bitwise OR,再取 XOR
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll n, k;
cin >> n >> k;
ll x, a, b, c;
cin >> x >> a >> b >> c;
vector<ll> vec(n);
vec[0] = x;
for (ll i = 1; i < n; i++) {
vec[i] = (vec[i - 1] * a % c + b) % c;
}
ll result = 0;
ll totalBlocks = (n + k - 1) / k;
vector<ll> suffix(k), prefix(k);
for (ll seg = 0; seg + 1 < totalBlocks; ++seg) {
ll base = seg * k;
ll end = min(n - 1, base + k - 1);
// Step 1: 預處理目前區塊的 suffix-OR
suffix[k - 1] = vec[end];
for (ll i = end - 1; i >= base; --i) suffix[i - base] = vec[i] | suffix[i - base + 1];
// Step 2: 預處理下一區塊的 prefix-OR
ll nextBase = (seg + 1) * k;
ll nextEnd = min(n - 1, nextBase + k - 1);
prefix[0] = vec[nextBase];
for (ll i = nextBase + 1; i <= nextEnd; ++i)
prefix[i - nextBase] = vec[i] | prefix[i - nextBase - 1];
// Step 3: 處理這個區塊起點的所有合法視窗
for (ll i = base; i <= end && i <= n - k; ++i) {
ll nextCount = i - base;
ll curCount = k - nextCount;
ll winOR;
if (nextCount == 0) {
winOR = suffix[0]; // 完全在目前區塊
} else {
winOR = suffix[k - curCount] | prefix[nextCount - 1];
}
result ^= winOR;
}
}
// 如果最後一區塊剛好長度 k,處理尾端視窗
if (n % k == 0) {
ll base = (totalBlocks - 1) * k;
ll end = n - 1;
suffix[k - 1] = vec[end];
for (ll i = end - 1; i >= base; --i) suffix[i - base] = vec[i] | suffix[i - base + 1];
result ^= suffix[0];
}
cout << result << '\n';
return 0;
}