Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 24a2428

Browse files
committed
灵茶の试炼 * 27 (无UT)
1 parent 4b77ab3 commit 24a2428

File tree

27 files changed

+3047
-0
lines changed

27 files changed

+3047
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package c282;
2+
3+
import java.util.ArrayList;
4+
import java.util.Comparator;
5+
import java.util.List;
6+
import java.util.Scanner;
7+
8+
public class Abc282_e {
9+
static int n, m;
10+
static int[] a;
11+
12+
public static void main(String[] args) {
13+
Scanner scanner = new Scanner(System.in);
14+
n = scanner.nextInt();
15+
m = scanner.nextInt();
16+
a = new int[n];
17+
for (int i = 0; i < n; i++) {
18+
a[i] = scanner.nextInt();
19+
}
20+
System.out.println(solve());
21+
}
22+
23+
record tuple(int v, int w, int wt) {
24+
}
25+
26+
private static String solve() {
27+
List<tuple> b = new ArrayList<>();
28+
for (int i = 0; i < n; i++) {
29+
int v = a[i];
30+
for (int j = i + 1; j < n; j++) {
31+
int w = a[j];
32+
b.add(new tuple(i, j, (int) ((quickPow(v, w, m) + quickPow(w, v, m)) % m)));
33+
}
34+
}
35+
b.sort(Comparator.comparingLong(o -> -o.wt));
36+
37+
long ans = 0;
38+
DSU dsu = new DSU(n);
39+
for (tuple e : b) {
40+
int v = e.v, w = e.w, wt = e.wt;
41+
int fv = dsu.find(v);
42+
int fw = dsu.find(w);
43+
if (fv != fw) {
44+
dsu.union(fv, fw);
45+
ans += wt;
46+
}
47+
}
48+
return String.valueOf(ans);
49+
}
50+
51+
static class DSU {
52+
int[] fa;
53+
54+
public DSU(int n) {
55+
fa = new int[n];
56+
for (int i = 0; i < n; i++) {
57+
fa[i] = i;
58+
}
59+
}
60+
61+
int find(int x) { // 查找
62+
return x == fa[x] ? fa[x] : (fa[x] = find(fa[x]));
63+
}
64+
65+
void union(int p, int q) { // 合并
66+
p = find(p);
67+
q = find(q);
68+
if (p == q) return;
69+
fa[q] = p;
70+
}
71+
}
72+
73+
// 快速幂 res = a^b % mod
74+
static long quickPow(long a, long b, long MOD) {
75+
long res = 1L;
76+
while (b > 0) {
77+
if ((b & 1) != 0) res = res * a % MOD;
78+
a = a * a % MOD;
79+
b >>= 1;
80+
}
81+
return res;
82+
}
83+
}
84+
/*
85+
E - Choose Two and Eat One
86+
https://atcoder.jp/contests/abc282/tasks/abc282_e
87+
88+
灵茶の试炼 2025年01月09日
89+
题目大意:
90+
输入 n(2≤n≤500) m(2≤m≤1e9) 和长为 n 的数组 a(1≤a[i]≤m-1)。
91+
重复如下操作 n-1 次:
92+
选择 a 中的两个数 x 和 y,得到 (pow(x,y)+pow(y,x))%m 分,然后从 a 中删除 x 或者 y。
93+
输出总得分的最大值。
94+
95+
看成有 n 个节点的完全图。
96+
每次操作相当于选择一条边,并删掉一个节点。
97+
由于选择的边,不会与已删除的点相连,所以选择的边不能构成环。
98+
于是 n-1 次选边后,我们得到的是一棵生成树。
99+
Kruskal/Prim 计算最大生成树即可,后者复杂度 O(n^2)。
100+
代码 https://atcoder.jp/contests/abc282/submissions/61218053
101+
======
102+
103+
Input 1
104+
4 10
105+
4 2 3 2
106+
Output 1
107+
20
108+
109+
Input 2
110+
20 100
111+
29 31 68 20 83 66 23 84 69 96 41 61 83 37 52 71 18 55 40 8
112+
Output 2
113+
1733
114+
*/
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package c286;
2+
3+
import java.util.Arrays;
4+
import java.util.Scanner;
5+
6+
public class Abc286_e {
7+
static Scanner scanner = new Scanner(System.in);
8+
static int n;
9+
static int[] a;
10+
11+
public static void main(String[] args) {
12+
n = scanner.nextInt();
13+
a = new int[n];
14+
for (int i = 0; i < n; i++) {
15+
a[i] = scanner.nextInt();
16+
}
17+
System.out.println(solve());
18+
}
19+
20+
static final int INF = (int) 1e9;
21+
22+
static class pair {
23+
int dis;
24+
long s;
25+
26+
public pair(int dis, long s) {
27+
this.dis = dis;
28+
this.s = s;
29+
}
30+
}
31+
32+
private static String solve() {
33+
pair[][] f = new pair[n][n];
34+
for (int i = 0; i < n; i++) {
35+
Arrays.setAll(f[i], e -> new pair(0, 0));
36+
}
37+
for (int i = 0; i < n; i++) {
38+
int v = a[i];
39+
String s = scanner.next();
40+
for (int j = 0; j < s.length(); j++) {
41+
char b = s.charAt(j);
42+
if (b == 'Y') {
43+
f[i][j] = new pair(1, v);
44+
} else {
45+
f[i][j].dis = INF;
46+
}
47+
}
48+
}
49+
50+
for (int k = 0; k < n; k++) {
51+
for (int i = 0; i < n; i++) {
52+
for (int j = 0; j < n; j++) {
53+
int d = f[i][k].dis + f[k][j].dis;
54+
long s = f[i][k].s + f[k][j].s;
55+
if (d < f[i][j].dis || d == f[i][j].dis && s > f[i][j].s) {
56+
f[i][j] = new pair(d, s);
57+
}
58+
}
59+
}
60+
}
61+
62+
int q = scanner.nextInt();
63+
String[] output = new String[q];
64+
for (int i = 0; i < q; i++) {
65+
int v = scanner.nextInt() - 1;
66+
int w = scanner.nextInt() - 1;
67+
pair p = f[v][w];
68+
if (p.dis == INF) {
69+
output[i] = "Impossible";
70+
} else {
71+
output[i] = p.dis + " " + (p.s + a[w]);
72+
}
73+
}
74+
return String.join(System.lineSeparator(), output);
75+
}
76+
}
77+
/*
78+
E - Souvenir
79+
https://atcoder.jp/contests/abc286/tasks/abc286_e
80+
81+
灵茶の试炼 2025年03月25日
82+
题目大意:
83+
输入 n(2≤n≤300) 和长为 n 的数组 a(1≤a[i]≤1e9),表示一个 n 个点的图,每个点的点权为 a[i]。
84+
然后输入一个 n*n 的 YN 矩阵 g,其中 g[i][j]=Y 表示有一条从 i 到 j 的有向边,边权为 1;g[i][j]=N 表示没有 i 到 j 的有向边。保证 g[i][i]=N。
85+
然后输入 q(1≤q≤n*(n-1)) 和 q 个询问,每个询问输入两个数 x 和 y,保证 x≠y,范围在 [1,n]。
86+
对于每个询问,输出两个数:
87+
1. 从 x 到 y 的最短路长度 d。
88+
2. 在所有从 x 到 y 的长为 d 的路径中,路径点权之和的最大值。
89+
如果无法从 x 到 y,改为输出 Impossible。
90+
91+
n 很小,用 Floyd 计算所有点对的最短路。
92+
算的同时,维护从 i 到 j 的点权和的最大值。
93+
注意 Floyd 是应用在边上的,为了计算路径点权之和,我们需要把点权放到边上。怎么做?
94+
可以在初始化时,对于边 i->j,把点权 a[i] 放到 i->j 上。也就是说 i->j 保存边权和点权 a[i]。
95+
最终回答询问时,把路径点权之和额外加上终点 y 的点权,就是最终答案。
96+
代码 https://atcoder.jp/contests/abc286/submissions/63232504
97+
======
98+
99+
Input 1
100+
5
101+
30 50 70 20 60
102+
NYYNN
103+
NNYNN
104+
NNNYY
105+
YNNNN
106+
YNNNN
107+
3
108+
1 3
109+
3 1
110+
4 5
111+
Output 1
112+
1 100
113+
2 160
114+
3 180
115+
116+
Input 2
117+
2
118+
100 100
119+
NN
120+
NN
121+
1
122+
1 2
123+
Output 2
124+
Impossible
125+
*/
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package c321;
2+
3+
import java.util.Arrays;
4+
import java.util.Scanner;
5+
import java.util.stream.Collectors;
6+
7+
public class Abc321_f {
8+
static Scanner scanner = new Scanner(System.in);
9+
static int q, k;
10+
11+
public static void main(String[] args) {
12+
q = scanner.nextInt();
13+
k = scanner.nextInt();
14+
System.out.println(solve());
15+
}
16+
17+
static final int MOD = 998244353;
18+
19+
private static String solve() {
20+
long[] f = new long[k + 1];
21+
f[0] = 1;
22+
23+
long[] ans = new long[q];
24+
for (int qi = 0; qi < q; qi++) {
25+
String op = scanner.next();
26+
int v = scanner.nextInt();
27+
if ("+".equals(op)) {
28+
for (int i = k; i >= v; i--) {
29+
f[i] = (f[i] + f[i - v]) % MOD;
30+
}
31+
} else {
32+
for (int i = v; i <= k; i++) {
33+
f[i] = (f[i] - f[i - v] + MOD) % MOD;
34+
}
35+
}
36+
ans[qi] = f[k];
37+
}
38+
return Arrays.stream(ans).mapToObj(String::valueOf).collect(Collectors.joining(System.lineSeparator()));
39+
}
40+
}
41+
/*
42+
F - #(subset sum = K) with Add and Erase
43+
https://atcoder.jp/contests/abc321/tasks/abc321_f
44+
45+
灵茶の试炼 2025年02月27日
46+
题目大意:
47+
输入 q(1≤n≤5000) 和 k(1≤k≤5000)。
48+
一开始有一个空箱子。输入 q 个操作:
49+
"+ v":把一个写有数字 v 的小球放入箱子。
50+
"- v":从箱子中移除一个写有数字 v 的小球,保证箱子中有这样的小球。
51+
v 的范围是 [1,5000]。
52+
每次操作后,输出有多少种方案,从箱子中选取一些球,元素和恰好等于 k。答案模 998244353。
53+
注意球是有区分的。
54+
55+
小球是有区别的,将这些小球视作一些物品,用 0-1 背包计算恰好装满容量为 k 的背包的方案数。
56+
添加数字的时候,按照 0-1 背包的方法转移,也就是 f[i] += f[i-v],倒序循环。
57+
删除数字的时候,撤销掉之前的转移,也就是 f[i] -= f[i-v],正序循环。
58+
注意取模。
59+
注意保证取模之后的结果非负。
60+
代码 https://atcoder.jp/contests/abc321/submissions/62943296
61+
问:为什么撤销是对的?
62+
答:可以这样理解,物品顺序不影响 f 的计算,那么当我取出数字 v 的时候,我可以把 "+ v" 调换到取出之前,也就是刚加进去就拿出来,这样之前写的 f[i] += f[i-v] 就可以立刻用 f[i] -= f[i-v] 撤销掉,f 现在是没有 x 的方案数。
63+
======
64+
65+
Input 1
66+
15 10
67+
+ 5
68+
+ 2
69+
+ 3
70+
- 2
71+
+ 5
72+
+ 10
73+
- 3
74+
+ 1
75+
+ 3
76+
+ 3
77+
- 5
78+
+ 1
79+
+ 7
80+
+ 4
81+
- 3
82+
Output 1
83+
0
84+
0
85+
1
86+
0
87+
1
88+
2
89+
2
90+
2
91+
2
92+
2
93+
1
94+
3
95+
5
96+
8
97+
5
98+
*/

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /