程式碼:(前綴和、後綴和、前綴奇數數量序列、後綴奇數數量序列、two pointers)
#include <iostream>using namespace std;int main() { cin.tie(0); ios::sync_with_stdio(0); int n, k; cin >> n >> k; long long arr[n], pre[n], suf[n], pre_odd[n], suf_odd[n];
cin >> arr[0]; pre[0] = arr[0]; pre_odd[0] = arr[0]%2;
for (int i = 1 ; i < n ; i ++) { cin >> arr[i]; pre[i] = arr[i] + pre[i-1]; pre_odd[i] = pre_odd[i-1] + arr[i]%2; }
suf[n-1] = arr[n-1]; suf_odd[n-1] = arr[n-1]%2;
for (int i = n-2 ; i > 0 ; i --) { suf[i] = arr[i] + suf[i+1]; suf_odd[i] = suf_odd[i+1] + arr[i]%2; }
int left, right; long long sum = 0, odd_cnt = 0, best = 0; for (left = -1 ; left < n ; left ++) { for (right = n ; right > left ; right --) { if (left == -1 && right == n) continue; if (left == -1) { if (suf[right] > k) break; if (suf_odd[right] * 2 == n - right) best = max(best, suf[right]); } else if (right == n) { if (pre[left] > k) break; if (pre_odd[left] * 2 == left+1) best = max(best, pre[left]); } else { sum = pre[left] + suf[right]; odd_cnt = pre_odd[left] + suf_odd[right]; if (sum > k) break; if (odd_cnt * 2 == left+1+n-right) best = max(best, sum); } } }
cout << best; return 0;}
結果:NA(20%),測資 #4 及之後都出現 記憶體區段錯誤
請問為何會RE??
程式碼:(前綴和、後綴和、前綴奇數數量序列、後綴奇數數量序列、two pointers)
#includeusing namespace std;int main() {cin.tie(0); ios::sync_with_stdio(0);int n, k;cin >> n >> k;long long arr[n], pre[n], suf[n], pre_odd[n], suf_odd[n];
cin >> arr[0];pre[0] = arr[0];pre_odd[0] = arr[0]%2;
for (int i = 1 ; i < n ; i ++) {cin >> arr[i];pre[i] = arr[i] + pre[i-1];pre_odd[i] = pre_odd[i-1] + arr[i]%2;}
suf[n-1] = arr[n-1];suf_odd[n-1] = arr[n-1]%2;
for (int i = n-2 ; i > 0 ; i --) {suf[i] = arr[i] + suf[i+1];suf_odd[i] = suf_odd[i+1] + arr[i]%2;}
int left, right;long long sum = 0, odd_cnt = 0, best = 0;for (left = -1 ; left < n ; left ++) {for (right = n ; right > left ; right --) {if (left == -1 && right == n) continue;if (left == -1) {if (suf[right] > k) break;if (suf_odd[right] * 2 == n - right) best = max(best, suf[right]);} else if (right == n) {if (pre[left] > k) break;if (pre_odd[left] * 2 == left+1) best = max(best, pre[left]);} else {sum = pre[left] + suf[right];odd_cnt = pre_odd[left] + suf_odd[right];if (sum > k) break;if (odd_cnt * 2 == left+1+n-right) best = max(best, sum);}}}
cout << best;return 0;}結果:NA(20%),測資 #4 及之後都出現 記憶體區段錯誤
請問為何會RE??
RE問題已解決(將陣列宣告於全域),但是TLE,請問怎麼辦?
程式碼:(前綴和、後綴和、前綴奇數數量序列、後綴奇數數量序列、two pointers)
#includeusing namespace std;int main() {cin.tie(0); ios::sync_with_stdio(0);int n, k;cin >> n >> k;long long arr[n], pre[n], suf[n], pre_odd[n], suf_odd[n];
cin >> arr[0];pre[0] = arr[0];pre_odd[0] = arr[0]%2;
for (int i = 1 ; i < n ; i ++) {cin >> arr[i];pre[i] = arr[i] + pre[i-1];pre_odd[i] = pre_odd[i-1] + arr[i]%2;}
suf[n-1] = arr[n-1];suf_odd[n-1] = arr[n-1]%2;
for (int i = n-2 ; i > 0 ; i --) {suf[i] = arr[i] + suf[i+1];suf_odd[i] = suf_odd[i+1] + arr[i]%2;}
int left, right;long long sum = 0, odd_cnt = 0, best = 0;for (left = -1 ; left < n ; left ++) {for (right = n ; right > left ; right --) {if (left == -1 && right == n) continue;if (left == -1) {if (suf[right] > k) break;if (suf_odd[right] * 2 == n - right) best = max(best, suf[right]);} else if (right == n) {if (pre[left] > k) break;if (pre_odd[left] * 2 == left+1) best = max(best, pre[left]);} else {sum = pre[left] + suf[right];odd_cnt = pre_odd[left] + suf_odd[right];if (sum > k) break;if (odd_cnt * 2 == left+1+n-right) best = max(best, sum);}}}
cout << best;return 0;}結果:NA(20%),測資 #4 及之後都出現 記憶體區段錯誤
請問為何會RE??
RE問題已解決(將陣列宣告於全域),但是TLE,請問怎麼辦?
在尋找答案時,使用雙層for-loop,時間複雜度為O(n^2),但n很大,所以用n log n的二分搜。
具體實作
我的方法是先把每個奇偶數量和位置存成map,枚舉右邊數字的後綴和所對應到的右座標,在利用最大值k以及最右邊為對應位置-1進行二分搜,還有考慮只選其中一邊的情形。
程式碼:(前綴和、後綴和、前綴奇數數量序列、後綴奇數數量序列、two pointers)
#includeusing namespace std;int main() {cin.tie(0); ios::sync_with_stdio(0);int n, k;cin >> n >> k;long long arr[n], pre[n], suf[n], pre_odd[n], suf_odd[n];
cin >> arr[0];pre[0] = arr[0];pre_odd[0] = arr[0]%2;
for (int i = 1 ; i < n ; i ++) {cin >> arr[i];pre[i] = arr[i] + pre[i-1];pre_odd[i] = pre_odd[i-1] + arr[i]%2;}
suf[n-1] = arr[n-1];suf_odd[n-1] = arr[n-1]%2;
for (int i = n-2 ; i > 0 ; i --) {suf[i] = arr[i] + suf[i+1];suf_odd[i] = suf_odd[i+1] + arr[i]%2;}
int left, right;long long sum = 0, odd_cnt = 0, best = 0;for (left = -1 ; left < n ; left ++) {for (right = n ; right > left ; right --) {if (left == -1 && right == n) continue;if (left == -1) {if (suf[right] > k) break;if (suf_odd[right] * 2 == n - right) best = max(best, suf[right]);} else if (right == n) {if (pre[left] > k) break;if (pre_odd[left] * 2 == left+1) best = max(best, pre[left]);} else {sum = pre[left] + suf[right];odd_cnt = pre_odd[left] + suf_odd[right];if (sum > k) break;if (odd_cnt * 2 == left+1+n-right) best = max(best, sum);}}}
cout << best;return 0;}結果:NA(20%),測資 #4 及之後都出現 記憶體區段錯誤
請問為何會RE??
RE問題已解決(將陣列宣告於全域),但是TLE,請問怎麼辦?
在尋找答案時,使用雙層for-loop,時間複雜度為O(n^2),但n很大,所以用n log n的二分搜。
具體實作
我的方法是先把每個奇偶數量和位置存成map,枚舉右邊數字的後綴和所對應到的右座標,在利用最大值k以及最右邊為對應位置-1進行二分搜,還有考慮只選其中一邊的情形。
突然想到似乎可以壓成O(n),連前綴都不用,結果範例測資就出錯了
#include <iostream>#define MAXN 300001using namespace std;long long arr[MAXN];int main() { cin.tie(0); ios::sync_with_stdio(0); long long n, k, selected = 0, cnt, odd_cnt = 0, best = 0; cin >> n >> k; cnt = n;
for (int i = 0 ; i < n ; i ++) { cin >> arr[i]; selected += arr[i]; odd_cnt += arr[i]%2; }
int left = -1, right = 0; while (left < n) { if (selected > k) { if (right == n-1) break; right ++; selected -= arr[right-1]; odd_cnt -= arr[right-1]%2; cnt --; } else { if (odd_cnt*2 == cnt) best = max(best, selected); left ++; selected += arr[left]; odd_cnt += arr[left]%2; cnt ++; } }
cout << best; return 0;}
請問為甚麼??
程式碼:(前綴和、後綴和、前綴奇數數量序列、後綴奇數數量序列、two pointers)
#includeusing namespace std;int main() {cin.tie(0); ios::sync_with_stdio(0);int n, k;cin >> n >> k;long long arr[n], pre[n], suf[n], pre_odd[n], suf_odd[n];
cin >> arr[0];pre[0] = arr[0];pre_odd[0] = arr[0]%2;
for (int i = 1 ; i < n ; i ++) {cin >> arr[i];pre[i] = arr[i] + pre[i-1];pre_odd[i] = pre_odd[i-1] + arr[i]%2;}
suf[n-1] = arr[n-1];suf_odd[n-1] = arr[n-1]%2;
for (int i = n-2 ; i > 0 ; i --) {suf[i] = arr[i] + suf[i+1];suf_odd[i] = suf_odd[i+1] + arr[i]%2;}
int left, right;long long sum = 0, odd_cnt = 0, best = 0;for (left = -1 ; left < n ; left ++) {for (right = n ; right > left ; right --) {if (left == -1 && right == n) continue;if (left == -1) {if (suf[right] > k) break;if (suf_odd[right] * 2 == n - right) best = max(best, suf[right]);} else if (right == n) {if (pre[left] > k) break;if (pre_odd[left] * 2 == left+1) best = max(best, pre[left]);} else {sum = pre[left] + suf[right];odd_cnt = pre_odd[left] + suf_odd[right];if (sum > k) break;if (odd_cnt * 2 == left+1+n-right) best = max(best, sum);}}}
cout << best;return 0;}結果:NA(20%),測資 #4 及之後都出現 記憶體區段錯誤
請問為何會RE??
RE問題已解決(將陣列宣告於全域),但是TLE,請問怎麼辦?
在尋找答案時,使用雙層for-loop,時間複雜度為O(n^2),但n很大,所以用n log n的二分搜。
具體實作
我的方法是先把每個奇偶數量和位置存成map,枚舉右邊數字的後綴和所對應到的右座標,在利用最大值k以及最右邊為對應位置-1進行二分搜,還有考慮只選其中一邊的情形。
突然想到似乎可以壓成O(n),連前綴都不用,結果範例測資就出錯了
#include#define MAXN 300001using namespace std;long long arr[MAXN];int main() {cin.tie(0); ios::sync_with_stdio(0);long long n, k, selected = 0, cnt, odd_cnt = 0, best = 0;cin >> n >> k;cnt = n;
for (int i = 0 ; i < n ; i ++) {cin >> arr[i];selected += arr[i];odd_cnt += arr[i]%2;}
int left = -1, right = 0;while (left < n) {if (selected > k) {if (right == n-1) break;right ++;selected -= arr[right-1];odd_cnt -= arr[right-1]%2;cnt --;} else {if (odd_cnt*2 == cnt) best = max(best, selected);left ++;selected += arr[left];odd_cnt += arr[left]%2;cnt ++;}}
cout << best;return 0;}請問為甚麼??
可以打註解或說明一下想法嗎