照例

1339A Filling Diamonds

这样的图形,用$n=1$的子图形去这样填,问有几种填法。

由于必有且仅有一个竖的,那么答案就是$n$,$O(1)$。

A.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <bits/stdc++.h>
using namespace std;

int main() {
int q;
cin >> q;
while (q--) {
int n;
cin >> n;
cout << n << endl;
}
return 0;
}

1339B Sorted Adjacent Differences

有一个序列,要求重排后,$|a_i-a_{i-1}|\leq |a_i-a_{i+1}|$,给出方案。

从小到大排序后从两端向中间取,差的绝对值一定越来越小,再反向输出,$O(n\log n)$。

B.cpp
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
#include <bits/stdc++.h>
using namespace std;

int main() {
int q;
cin >> q;
while (q--) {
int n;
cin >> n;
vector<int> a(n);
for (int &i : a) cin >> i;
sort(a.begin(), a.end());

vector<int> ans;
int l = 0, r = n - 1;
while (l < r) {
ans.emplace_back(a[l++]);
ans.emplace_back(a[r--]);
}
if (l == r) ans.emplace_back(a[l]);
for (int i = n - 1; i >= 0; --i) {
cout << ans[i] << ' ';
}
cout << endl;
}
return 0;
}

1338A Powered Addition

有一个序列,在第$x$次操作可以选一些数给它$+=2^{x-1}$,问最少到第几次操作结束后序列可以变为非减的。

最后的序列一定是阶梯状的,那么就是找前面的最大值和后面较小值的最大的差,答案就是差的二进制位数,$O(n)$。

C.cpp
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
#include <bits/stdc++.h>
using namespace std;

int main() {
int q;
cin >> q;
while (q--) {
int n;
ll mx = -1e9, mxx = 0;
cin >> n;
vector<ll> a(n);
for (ll &i : a) cin >> i;
for (int i = 0; i < n; ++i) {
mx = max(mx, a[i]);
mxx = max(mxx, mx - a[i]);
}

ll ans = 0;
for (int i = 0; i < 33; ++i) {
if ((mxx >> i) & 1)
ans = i + 1;
}
cout << ans << endl;
}
return 0;
}

1338B Edge Weight Assignment

有一颗树,边有边权,要求叶子到叶子的路径权值异或和为$0$,问最少用几种数字和最多用几种。

  • 最少的答案可以很明显想到和叶子间的路径长度奇偶性有关,如果距离都是偶数,那么用一样的数就可以了;那么如果有一个或以上的奇数呢,首先一定会有偶数的距离(或只有一条奇数长度链),那么用$1,2,3$,将$1$放在偶数那些叶子那条边上,剩下用其他的填,一定有方案。
  • 最多答案的话,答案最多是总边数,而且可以发现如果有距离为$2$的叶子对的话,这两边必须相同,手写一下好像其他一定有方案(其实不会证,看官方题解叭)。
    $O(n)$(莽了一发过了。。。)
D.cpp
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
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;

int has[N][2], f;
vector<int> g[N];

void dfs(int u, int fa = 0) {
if (g[u].size() == 1) {
has[u][0] = 1;
return;
}
for (int v : g[u]) {
if (v == fa) continue;
dfs(v, u);
has[u][1] |= has[v][0];
has[u][0] |= has[v][1];
}
if (has[u][0] && has[u][1]) f = 1;
}

int main() {
int n;
cin >> n;
for (int i = 1, u, v; i < n; ++i) {
cin >> u >> v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}

int ans = 0, rt = 1;
for (int i = 1; i <= n; ++i) {
int t = -1;
for (int v : g[i]) {
if (g[v].size() == 1) ++t;
}
if (g[i].size() > 1) rt = i;
if (t > 0) ans += t;
}
dfs(rt);

ans = n - 1 - ans;
if (f) cout << "3 ";
else cout << "1 ";
cout << ans << endl;
return 0;
}