每日一题-20250810

Leetcode

869. 重新排序得到 2 的幂/第 93 场周赛 Q2/Rating 1505

  • 排序
  • 哈希

考虑到 1n1091 \leq n \leq 10^9,可以直接枚举这个范围内的所有 22 的幂进行哈希,只需要判断给定数字的哈希是否存在即可。

1
2
3
4
5
6
p = [sorted(str(1 << i)) for i in range(0, 31)]

class Solution:
def reorderedPowerOf2(self, n: int) -> bool:
s = sorted(str(n))
return s in p

Codeforces

easy

CF2123E/Rating 1400

  • 思维
  • 差分
  • 前缀和
  • 正难则反

直接计算原问题是困难的,但是对于已经出现过的数,维护如何让序列的 mex=i\mathrm{mex} = i 是容易的:

  • 把所有的 ii 都删掉可以得到最少的删除次数,即 cnti\mathrm{cnt}_i
  • 序列中只保留 0i10 \sim i - 1 可以得到最多的删除次数,即 nin - i

这是一个区间加法,维护差分,前缀和即可得到答案。

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
#include<bits/stdc++.h>
#define ioclear std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);
#define endl '\n'
#define CLOCK (1e3 * clock() / CLOCKS_PER_SEC)
#define all(x) (x).begin(), (x).end()

#ifdef LOCAL
#define dmp(x) std::cerr << __LINE__ << " " << #x << " " << x << endl;
#else
#define dmp(x) void(0)
#endif

using i64 = long long;

void solve()
{
int n;
std::cin >> n;
std::vector<int> a(n + 1);
std::map<int, int> mp;
for(int i = 1; i <= n; i++)
{
std::cin >> a[i];
mp[a[i]]++;
}
std::vector<int> ans(n + 1);
// 考虑有多少种情况能使得 mex = i
// min: mp[i]
// max: n - i (仅保留 0 to i - 1)
for(int i = 0; i <= n; i++)
{
ans[mp[i]]++;
if(i)
ans[n - i + 1]--;
// mex 不会变大
if(!mp[i])
break;
}
for(int i = 1; i <= n; i++)
ans[i] += ans[i - 1];
for(int i = 0; i <= n; i++)
std::cout << ans[i] << " \n"[i == n];

}

int main()
{
#ifdef ONLINE_JUDGE
ioclear;
#endif

int t = 1;
std::cin >> t;
while(t--)
solve();

// std::cerr << "USED " << CLOCK << " ms";
}

hard

CF2065F/Rating 1700

  • 树形结构
  • dfs
  • 脑筋急转弯
  • 分类讨论

分类讨论路径长度 kk

  • k=2k = 2:只能是相邻的两个点点权相同;
  • k=3k = 3:两个点权相同的点之间的距离 1\leq 1
  • k=4k = 4:路径上至少要有三个点权相同的点,两两之间的限制仍然与 k=3k = 3 时一致。

继续推广,发现只要满足 k=3k = 3 时的限制即可。

dfs 枚举一个点,统计其周围邻居的点权,判断其中是否有出现次数 2\geq 2 的点权即可。

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
63
64
65
66
67
68
69
70
71
72
#include<bits/stdc++.h>
#define ioclear std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);
#define endl '\n'
#define CLOCK (1e3 * clock() / CLOCKS_PER_SEC)
#define all(x) (x).begin(), (x).end()

#ifdef LOCAL
#define dmp(x) std::cerr << __LINE__ << " " << #x << " " << x << endl;
#else
#define dmp(x) void(0)
#endif

using i64 = long long;

void solve()
{
int n;
std::cin >> n;
std::vector<int> a(n + 1);
for(int i = 1; i <= n; i++)
std::cin >> a[i];
std::vector<std::vector<int>> edge(n + 1);
auto add = [&](int x, int y)
{
edge[x].push_back(y);
};
for(int i = 1; i < n; i++)
{
int x, y;
std::cin >> x >> y;
add(x, y);
add(y, x);
}
std::vector<int> ans(n + 1, 0), cnt(n + 1, 0);
auto dfs = [&](auto&& self, int cur, int fa) -> void
{
cnt[a[cur]]++;
for(auto v: edge[cur])
cnt[a[v]]++;
for(auto v: edge[cur])
if(cnt[a[v]] >= 2)
ans[a[v]] = 1;
for(auto v: edge[cur])
cnt[a[v]]--;
cnt[a[cur]]--;
for(auto v: edge[cur])
{
if(v == fa)
continue;
self(self, v, cur);
}
return;
};
dfs(dfs, 1, 0);
for(int i = 1; i <= n; i++)
std::cout << ans[i];
std::cout << endl;
}

int main()
{
#ifdef ONLINE_JUDGE
ioclear;
#endif

int t = 1;
std::cin >> t;
while(t--)
solve();

// std::cerr << "USED " << CLOCK << " ms";
}