CF-Div2-832 D. Yet Another Problem(bitmask&结论)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF-Div2-832 D. Yet Another Problem(bitmask&结论)相关的知识,希望对你有一定的参考价值。
CF-Div2-832 D. Yet Another Problem(bitmask&结论)
为了方便设每次询问 [ l , r ] [l,r] [l,r] 的长度为 n n n。
注意到:
每次操作不会影响 X o r ( l , r ) Xor(l,r) Xor(l,r)的结果。
所以必要条件1:
X
o
r
(
l
,
r
)
=
0
Xor(l,r)=0
Xor(l,r)=0
然后我们可以发现,我们可以将从
l
l
l开始的前缀异或和分为两个部分,长度为奇数的前缀和长度为偶数的。
每次操作后,比如我们对 [ x , y ] , l ≤ x ≤ y ≤ r [x,y],l\\le x\\le y\\le r [x,y],l≤x≤y≤r 操作。
那么下标在 [ l , x − 1 ] [l,x-1] [l,x−1] 和 [ y + 1 , r ] [y+1,r] [y+1,r] 的下标前缀答案不会改变。
而下标在 [ x , y ] [x,y] [x,y]之间的前缀异或和结果要么是 X o r ( l , y ) Xor(l,y) Xor(l,y) 要么 X o r ( l , x − 1 ) Xor(l,x-1) Xor(l,x−1)
也就是说这两个集合不会相互影响,且每次操作只会使集合大小非递增。
因此要想最终 X o r ( l , r ) = 0 Xor(l,r)=0 Xor(l,r)=0,显然这两个集合都必须包含前缀异或和为 0 0 0的下标。
更进一步,对于区间 1 ≤ l ≤ r ≤ n 1\\le l\\le r\\le n 1≤l≤r≤n,显然 X o r ( l , r ) = 0 Xor(l,r)=0 Xor(l,r)=0 而且必须存在
X o r ( 1 , r ) = X o r ( 1 , x ) , x m o d 2 ≠ r m o d 2 Xor(1,r) =Xor(1,x) , x\\mod2\\ne r\\mod 2 Xor(1,r)=Xor(1,x),xmod2=rmod2
那么 X o r ( l , r ) = X o r ( x + 1 , r ) = X o r ( l , x ) = 0 Xor(l,r)=Xor(x+1,r)=Xor(l,x)=0 Xor(l,r)=Xor(x+1,r)=Xor(l,x)=0
不满足必要条件1,无解。
如果区间全为0,答案为0.
如果 l e n ( l , r ) len(l,r) len(l,r)为奇数,答案为1。
否则如果 a [ l ] = 0 ∣ ∣ a [ r ] = 0 a[l]=0||a[r]=0 a[l]=0∣∣a[r]=0 则可以转情况2,答案为1.
否则如果 l a s t r ≥ l last_r \\ge l lastr≥l 保证 [ l a s t l + 1 , r ] [last_l+1,r] [lastl+1,r] 异或和为0。操作次数为2。
否则无解。
int _runtimeTerror_()
int n, Q;
cin >> n >> Q;
map<int, int> odd, even;
vector<int> last_nz(n + 1, 0), last(n + 1, -1), pxor(n + 1, 0);
vector<int> a(n + 1);
even[0] = 0;
int cur = 0;
for(int i=1;i<=n;++i)
cin >> a[i];
cur ^= a[i];
pxor[i] = cur;
if(a[i] == 0)
last_nz[i] = last_nz[i - 1];
else
last_nz[i] = i;
if(i & 1)
if(even.count(cur))
last[i] = even[cur];
odd[cur] = i;
else
if(odd.count(cur))
last[i] = odd[cur];
even[cur] = i;
while(Q--)
int l, r;
cin >> l >> r;
if(pxor[l - 1] != pxor[r])
cout << "-1\\n";
else if(last_nz[r] < l)
cout << "0\\n";
else if(r % 2 == l % 2)
cout << "1\\n";
else if(a[l] == 0 or a[r] == 0)
cout << "1\\n";
else if(last[r] >= l)
cout << "2\\n";
else
cout << "-1\\n";
return 0;
以上是关于CF-Div2-832 D. Yet Another Problem(bitmask&结论)的主要内容,如果未能解决你的问题,请参考以下文章
D. Yet Another Yet Another Task (ST表模版 + 单调队列)
CF-1359 D. Yet Another Yet Another Task ST表+单调队列
CF-1359 D. Yet Another Yet Another Task ST表+单调队列
Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task
Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task