CF1872E
\(Solution\)
性質題。
\(\mathcal{part\ 1}\)
\(n\leq 10^5\) 的數據范圍一定會讓人敏銳的想到線段樹,本題可以使用線段樹求解,但是細節很多,在考場上很難調對。
\(\mathcal{part\ 2}\)
考慮異或的性質:偶數次異或同一個數,對答案沒有影響。證明請讀者自行思考,過程并不繁瑣。
再次觀察操作 \(1\)。對于取反操作,被選的數字變為不選,不選的數字變為被選的。可以通過直接異或上區間異或和得到。通過異或的性質我們可以得到一個數異或自己奇數次得到的答案是自己,偶數次是 \(0\),恰好滿足。
分別維護“\(0,1\) 區間” ,使它們的異或和分別等于 \(b0,b1\),然后用剛才提到的方法維護即可。
那么對于操作 \(2\),直接輸出 \(b0\) 或 \(b1\)。
復雜度 \(\Theta(\sum n)\)。
\(\mathcal{Code}\)
#define int long long
const int N = 1e6 + 5;
namespace Jelly {
int n, ans = 0, a[N], q, b[N], b1, b0;
char s[N];
int main() {
Read(n);
b0 = b1 = 0;
for(int i = 1; i <= n; i ++) Read(a[i]);
Read(s, q);
for(int i = 1; i <= n; i ++) {
b[i] = b[i - 1] ^ a[i];
b0 = b0 ^ (s[i - 1] == '1' ? 0ll : a[i]);
b1 = b1 ^ (s[i - 1] == '1' ? a[i] : 0ll);
}
while(q --) {
int opt, x, y;
Read(opt);
if(opt == 2) {
Read(x);
if(x == 0) Write(b0, ' ');
else Write(b1, ' ');
}
else Read(x, y), b0 ^= (b[y] ^ b[x - 1]), b1 ^= (b[y] ^ b[x - 1]);
}
Writeln();
return 0;
}
}
signed main() {
int T = 1;
Read(T);
while(T --) Jelly::main();
return 0;
}

浙公網安備 33010602011771號