標簽 :題解
1592A - Геймер Хемосе
1592B - Hemose Shopping
我們發現,在這個數組中,左右兩部分是可以任意交換的。
如 :\(x = 5\), 有數組 \([7, 1, 5, 4, 3, 2, 6]\), 發現完全可以排列成\([1, 2, 5, 4, 3, 6, 7]\)
證 :\(a[i]\) 與 \(a[i + d](d < x)\), 可以通過 $ a[i + d + x] $ 實現交換,故$ [1, n - x] \cup [x + 1, n]$ 可以相當於 \(sort\)。剩下的沒辦法,動都動不了,只能判斷是否不降, 若不降就是 \(\text{YES}\), 否則 \(\text{NO}\) 。
1592C - Bakry and Partitioning
提一嘴 :聯通塊數是\(2 \sim k\),不是強制 \(k\)。
可以發現,要么兩個聯通塊, 要么三個聯通塊,其他的情況都等價於這兩種情況。
- 分為兩個聯通塊, \(\bigoplus allsum = 0\) 隨便刪一條邊即可。
- 發現 \(\bigoplus allsum = \bigoplus everyblocksum\), \(dfs\) 一遍找子樹 \(\bigoplus sum = \bigoplus allsum\), 統計一下,個數大於等於2即可。
注意:已經等於\(\bigoplus allsum\)的要割掉,即返回 \(0\)。
1592E - Скучающий Бакри
易知,應該在每一位上考慮。
結論 :當一段區間有貢獻,當且僅當這一段區間全為 \(1\)。證明易知。
以此結論,我們考慮每個區間 \([l, r]\) 模擬兩數 \(xorsum, andsum\) 二進制位比較的過程:從高到低,某一位 \(1>0\)。
當我們比較到第 \(k\) 位時,我們所比較的 \(andsum = 1\) 時,\(xorsum\) 必然為 \(0\), 故第 \(1\) 到 \(k - 1\) 位的 \(xorsum\) 與 \(andsum\) 均為 \(0\)。
故統計當前異或和,當此時\(x\)異或和 \(\bigoplus_{begin} ^{x}\) 在以前出現過\(\bigoplus_{begin} ^{y}\)時,這一段的異或和\(\bigoplus_{y + 1} ^{x}\)為\(0\),故統計當前答案 \(x- y\) 即可。
#include <bits/stdc++.h>
using namespace std;
int read() {
int f = 1, x = 0; char c = getchar();
while(!isdigit(c)) {if(c == '-') f = -f; c = getchar();}
while(isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();}
return x * f;
}
const int N = 1e6 + 5;
int n, m, p, q, ans, a[N];
unordered_map <int, int> mp;
int main() {
n = read();
for(int i = 1; i <= n; i ++) a[i] = read();
for(int i = 20, sum = 0, tmp; i >= 0; sum = 0, i --) {
mp.clear(), mp[0] = 1;
for(int j = 1; j <= n; j ++) {
// cout << int((a[j] >> i) & 1) << " " ;
if(!((a[j] >> i) & 1)) {
sum = 0; mp.clear(); mp[0] = j + 1;
continue;
}
sum ^= a[j]; tmp = (sum >> i) << i;
if(!mp[tmp])
mp[tmp] = j + 1;
else
ans = max(ans, j - mp[tmp] + 1);
}
// cout << "\n";
}
cout << ans;
return 0;
}