神秘并查集。
https://codeforces.com/problemset/problem/2033/E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
void solve() {
int n;
cin >> n;
DSU dsu(n);
for (int i = 0; i < n; i ++) {
int x;
cin >> x;
x --;
dsu.merge(i, x);
}
set<int> c;
for (int i = 0; i < n; i ++) {
c.insert(dsu.find(i));
}
int ans = 0;
for (auto &x : c)
ans += (dsu.size(x) + 1) / 2 - 1;
cout << ans << "\n";
}
|
神秘交互题。
https://codeforces.com/problemset/problem/2013/C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
void solve() {
int n;
cin >> n;
auto ask = [&](const string& t) {
cout << "? " << t << endl;
int ret;
cin >> ret;
if (ret == -1)
exit(0);
return ret;
};
string ans = "";
while (ans.size() < n) {
if (ask(ans + "0")) {
ans += "0";
continue;
}
if (ask(ans + "1")) {
ans += "1";
continue;
}
break;
}
while (ans.size() < n) {
if (ask("0" + ans)) {
ans = "0" + ans;
continue;
}
ans = "1" + ans;
}
cout << "! " << ans << endl;
}
|
神秘位运算。
https://codeforces.com/problemset/problem/2020/C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
void solve() {
int b, c, d;
cin >> b >> c >> d;
int a = 0;
int mask = 1;
for (int i = 0; i < 62; i ++) {
int bb = !!(b & mask), cc = !!(c & mask), dd = !!(d & mask);
if (bb and not cc and not dd or not bb and cc and dd) {
cout << "-1\n";
return;
}
if (bb and cc) {
a += (1ll - dd) * mask;
} else {
a += dd * mask;
}
mask <<= 1;
}
cout << a << "\n";
}
|
极其神秘的位运算。
https://codeforces.com/problemset/problem/2057/C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int l, r;
cin >> l >> r;
// 固定 a = l, c = r,构造 b
int b = 0; // 用来构造 b 的值
int tp = -1; // 第一个 l 与 r 不同的位(从高位开始找)
// 假设数最多 32 位,从 31 到 0
for(int i = 31; i >= 0; i--){
if (((l >> i) & 1LL) != ((r >> i) & 1LL)) {
tp = i;
break;
}
}
// 注意:题目保证 l < r ,因此 tp 一定不为 -1
// 1. 对于高于 tp 的位,l 和 r 均相同,直接复制
for (int i = tp+1; i < 32; i++){
if((l >> i) & 1LL)
b |= (1LL << i);
}
// 2. 对于从 tp 到 0 的位,先对那些 l 和 r 相同的位,令 b_i = l_i ⊕ 1
for (int i = tp; i >= 0; i--){
if (((l >> i) & 1LL) == ((r >> i) & 1LL)){
// 令 b_i = (l_i XOR 1)
if (((l >> i) & 1LL) == 0)
b |= (1LL << i); // 0^1 = 1
// 如果 l_i 为 1,则 b_i 取 0;这里 b_i 默认已是 0,所以不用处理
}
}
// 3. 对于从 tp 到 0 的位,处理那些 l 与 r 不同的位:
for (int i = tp; i >= 0; i--){
if (((l >> i) & 1LL) != ((r >> i) & 1LL)){
// 尝试置 1
b |= (1LL << i);
// 如果设置后 b 超过或等于 r,则把这一位还原为 0
if (b >= r)
b &= ~(1LL << i);
}
}
// 保证最终 l < b < r
if(b <= l) b = l + 1;
if(b >= r) b = r - 1;
cout << l << " " << b << " " << r << "\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
|