ABC293题解ABCDEG
A
1 |
|
B
1 |
|
C
简单dfs1
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
using namespace std;
using i64 = long long;
int way[2][2] = { 0, 1, 1, 0 };
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector e(n + 1, vector<int> (m + 1));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> e[i][j];
}
}
int ans = 0;
set<int> is;
vector vis(n + 1, vector<int> (m + 1));
auto dfs = [&](auto self, int x, int y) -> void {
if (x == n && y == m) {
ans++;
return;
}
is.insert(e[x][y]);
vis[x][y] = 1;
for (int i = 0; i < 2; i++) {
int dx = x + way[i][0];
int dy = y + way[i][1];
if (dx > 0 && dy > 0 && dx <= n && dy <= m && !vis[dx][dy] && !is.count(e[dx][dy])) {
self(self, dx, dy);
}
}
vis[x][y] = 0;
is.erase(e[x][y]);
};
vis[1][1] = 1;
is.insert(e[1][1]);
dfs(dfs, 1, 1);
cout << ans << '\n';
return 0;
}
D - Tying Rope
观察题意, 发现绳子之间绑起来可以使用并查集模拟, 对于没绑起来的绳子并到一个集合,如果遍历到已经在同一个集合里的两个绳子绑起来,说明两个绳子打结(成圈了),打个标记即可,最后扫一遍统计答案
1 |
|
E - Geometric Progression
给定整数 AA , XX 和 MM ,求 ∑i=0X−1Aii=0∑X−1Ai ,模 MM 。
题解:
可以学到很多东西, 首先用高中等比数列推出了答案是 $(A^q - 1) / (A - 1)$ ,直接使用乘法逆元(费马小定理)交上求一发,wa了13个,以为是精度问题,以前也没写过取模类,就去自己学习并写了一个板子如下:
1 | struct ModInt { |
之后使用取模类交上去,发现wa的地方一模一样,没招了做不出来。。。
错误原因是: 用乘法逆元直接求没办法保证除数和被除数互质,而逆元需要在互质的情况下才准确(不论是exgcd求还是费马), 那么我们应该另辟蹊径。
发现 $A^0 + A^1 + … + A^X$ 可以分以下两个情况讨论
奇数:
偶数:
之后递归求解答案
1 |
|
这样避免了求逆元。
G - Triple Index
给定一个长度为 NN 的正整数序列 (A1,A2,…,AN)(A1,A2,…,AN) ,并查询该序列的 QQ 。
对于每个 q=1,2,…,Qq=1,2,…,Q , qq \第一个查询将为您提供一个整数对 (lq,rq)(lq,rq) ;
输出整数三元组 (i,j,k)(i,j,k) 的个数,如下
- lq≤i<j<k≤rqlq≤i<j<k≤rq ,和
—— Ai=Aj=AkAi=Aj=Ak 。
- 题解 : 莫队板子, 每次加入或删除一个元素,如果这个元素个数 >= 3了, 那么固定这个元素, 可能的情况是在剩下 (x - 1) 个元素选一个, 后再(x - 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
73
74
75
76
77
78
79
80
81
82
83
using namespace std;
using i64 = long long;
struct Query {
int l, r, id;
};
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
vector<Query> que(q);
for (int i = 0; i < q; i++) {
int l, r;
cin >> l >> r;
que[i] = { l, r, i };
}
int len = sqrt(n);
ranges::sort(que, [&](const Query& p, const Query& q) {
int as = (p.l - 1) / len + 1;
int bs = (q.l - 1) / len + 1;
if (as != bs) return as < bs;
else return p.r < q.r;
});
i64 cur = 0;
vector<int> cnt(1e6);
auto add = [&](int pos) -> void {
cnt[a[pos]]++;
if (cnt[a[pos]] >= 3) {
cur += (cnt[a[pos]] - 1) * (cnt[a[pos]] - 2) / 2;
}
};
auto del = [&](int pos) -> void {
if (cnt[a[pos]] >= 3) {
cur -= (cnt[a[pos]] - 1) * (cnt[a[pos]] - 2) / 2;
}
cnt[a[pos]]--;
};
int nowr = 0, nowl = 1;
vector<int> ans(q);
for (auto &x : que) {
auto [l, r, id] = x;
while (nowr < r) {
nowr++;
add(nowr);
}
while (nowr > r) {
del(nowr);
nowr--;
}
while (nowl < l) {
del(nowl);
nowl++;
}
while (nowl > l) {
nowl--;
add(nowl);
}
ans[id] = cur;
}
for (int i = 0; i < q; i++) {
cout << ans[i] << "\n";
}
return 0;
}
F - Zero or One
等待补题
