E1. Bitwise Queries (Easy Version)
a+b=(a&b)+(a∣b)a+b=(a\&b)+(a|b)a+b=(a&b)+(a∣b)
根據上述式子用333次$&和333次∣|∣操作求出a1+a2,a2+a3,a1+a3a_1+a_2,a_2+a_3,a_1+a_3a1?+a2?,a2?+a3?,a1?+a3?由此得出a1,a2,a3a_1,a_2,a_3a1?,a2?,a3?
根據a1⊕ai=xa_1\oplus a_i=xa1?⊕ai?=x于是ai=x⊕a1a_i=x\oplus a_1ai?=x⊕a1?可使用n?3n-3n?3次⊕\oplus⊕操作得出答案
共計n+3n+3n+3次。。。
大佬題解
a+b=(a⊕b)+2×(a&b)a+b=(a\oplus b)+2×(a\&b)a+b=(a⊕b)+2×(a&b)
如果已知a1⊕a2,a2⊕a3a_1\oplus a_2,a_2 \oplus a_3a1?⊕a2?,a2?⊕a3?那么a1⊕a3=(a1⊕a2)⊕(a2⊕a3)a_1\oplus a_3=(a_1\oplus a_2)\oplus (a_2\oplus a_3)a1?⊕a3?=(a1?⊕a2?)⊕(a2?⊕a3?)
那么只需用555次就可以知道a1,a2,a3a_1,a_2,a_3a1?,a2?,a3?最終用n+2n+2n+2次得出答案。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std
;
typedef long long ll
;
typedef pair
<int,int> pii
;
const int mod
=998244353;
const int N
=100010;
int x
,y
,z
;
void prework()
{int ab1
,ab2
,ac1
,ac2
,bc1
,bc2
;printf("XOR 1 2\n");fflush(stdout);cin
>>ab1
;printf("AND 1 2\n");fflush(stdout);cin
>>ab2
;printf("XOR 1 3\n");fflush(stdout);cin
>>ac1
;printf("AND 1 3\n");fflush(stdout);cin
>>ac2
;bc1
= ab1
^ ac1
;printf("AND 2 3\n");fflush(stdout);cin
>>bc2
;x
=ab1
+2*ab2
;y
=ac1
+2*ac2
;z
=bc1
+2*bc2
;
}
int main()
{IO
;int T
=1;while(T
--){int n
;cin
>>n
;vector
<int> ans(n
+1);prework();ans
[1]=(x
+y
-z
)/2;ans
[2]=(x
+z
-y
)/2;ans
[3]=(y
+z
-x
)/2;for(int i
=4;i
<=n
;i
++){int tmp
;printf("XOR 1 %d\n",i
);fflush(stdout);cin
>>tmp
;ans
[i
]=tmp
^ans
[1];}cout
<<"! ";for(int i
=1;i
<=n
;i
++) cout
<<ans
[i
]<<' ';cout
<<'\n';}return 0;
}
E2. Bitwise Queries (Hard Version)
大佬題解
同樣只要我們能確認一個值,其余的值都能通過異或來得到。由此我們目標是確定一個值。
注意到0<xi<n?10<x_i<n-10<xi?<n?1,由此數組有兩種情況
①對于數組元素重復的情況,我們首先進行n?1n-1n?1次x1⊕xix_1\oplus x_ix1?⊕xi?將異或值記入數組aia_iai?,不難發現其中肯定存在相同的值,只要記錄相同值的位置i,ji,ji,j那么只需要進行一次xi&xjx_i\&x_jxi?&xj?即可知道xix_ixi?和xjx_jxj?,那么就能根據aia_iai?或者aja_jaj?得出x1x_1x1?進而得出答案。操作nnn次
②如果不存在那么一定有某個數與第一個數相差1,ai=1a_i=1ai?=1,即xi⊕x1=1x_i\oplus x_1=1xi?⊕x1?=1,于是 不難得知x1x_1x1?和xix_ixi?分別是(x1&xi)(x_1\& x_i)(x1?&xi?)和(x1&xi)⊕1(x_1\& x_i)\oplus1(x1?&xi?)⊕1
然后隨便找一個與第一個數奇偶性相同的數(ai&1=0a_i\&1=0ai?&1=0)用一次&\&&操作x1&xix_1\&x_ix1?&xi?的奇偶性即是x1x_1x1?的奇偶性,于是可以得出x1x_1x1?。操作n+1n+1n+1次
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std
;
typedef long long ll
;
typedef pair
<int,int> pii
;
const int mod
=998244353;
const int N
=200010;
int a
[N
];
map
<int,int> pos
;
int main()
{int T
=1;while(T
--){int n
;cin
>>n
;pos
.clear();pos
[0]=1;int k
=0,v
;for(int i
=2;i
<=n
;i
++){printf("XOR 1 %d\n",i
);fflush(stdout);cin
>>a
[i
];if(pos
[a
[i
]]&&!k
){printf("AND %d %d\n",pos
[a
[i
]],i
);fflush(stdout);cin
>>v
;k
=i
;}pos
[a
[i
]]=i
;}if(k
) a
[1]=a
[k
]^v
;else{printf("AND 1 %d\n",pos
[1]);fflush(stdout);cin
>>a
[1];for(auto t
:pos
){if((t
.first
&1)||t
.second
==1) continue;printf("AND 1 %d\n",t
.second
);fflush(stdout);int c
; cin
>>c
;if(c
&1) a
[1]^=1;break;}}cout
<<"! "<<a
[1]<<' ';for(int i
=2;i
<=n
;i
++) cout
<<(a
[i
]^a
[1])<<' ';cout
<<'\n';}return 0;
}
要加油哦~
總結
以上是生活随笔為你收集整理的codeforces1451 E. Bitwise Queries(位运算妙用)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。