This commit is contained in:
HuangHai
2025-08-30 18:35:01 +08:00
commit 1f397eca87
6258 changed files with 1487241 additions and 0 deletions

BIN
TangDou/JiShuanKe/2023-03-06/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,24 @@
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL a[N], b[N], s[N];
LL n, m;
LL cnt;
int main() {
freopen("city.in", "r", stdin);
freopen("city.out", "w", stdout);
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++) {
cnt += a[i];
if (cnt >= m) {
cout << b[i] << endl;
return 0;
}
}
return 0;
}

View File

@@ -0,0 +1,58 @@
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2100, M = N << 1;
const int MOD = 998244353;
int e[M], h[N], idx, ne[M];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int n;
int limit[N]; // 以u为根的子树中数量上限
int st[N]; // 是不是访问过
LL f[N][N];
void dfs(int u) {
st[u] = 1; // 访问过了
f[u][0] = 1; // u子树中,放0个苹果的方案是1,此时只能是不管有多少个子结点,都是啥也不能放,方案唯一
if (limit[u]) f[u][1] = 1; // 在u子树中,如果只放1个的话,那么必然是放在u节点上,否则u子树就不存在的,此时方案数是1
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (st[v]) continue;
dfs(v);
// 分组背包
for (int j = limit[u]; j >= 0; j--) // 枚举u子树体积,倒序降维
// Q:为什么这里k=0开始是错的呢?
for (int k = 1; k <= min(j, limit[v]); k++) // 枚举决策,v子树中放资源k个
f[u][j] = (f[u][j] + f[v][k] * f[u][j - k]) % MOD;
}
}
int main() {
freopen("appletree.in", "r", stdin);
freopen("appletree.out", "w", stdout);
memset(h, -1, sizeof h);
cin >> n;
for (int i = 1; i <= n; i++) cin >> limit[i];
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a); // 无向图
}
dfs(1);
int res = 0;
for (int i = 0; i <= limit[1]; i++) res = (res + f[1][i]) % MOD;
printf("%d\n", res);
return 0;
}

View File

@@ -0,0 +1,9 @@
#include <bits/stdc++.h>
using namespace std;
int main() {
int h, m, s;
cin >> h >> m >> s;
cout << h * 3600 + m * 60 + s << endl;
return 0;
}

View File

@@ -0,0 +1,6 @@
5
1 1 1 0 0
1 2
1 3
2 4
2 5

View File

@@ -0,0 +1 @@
4

View File

@@ -0,0 +1,3 @@
4 5
1 2 3 4
4 3 2 1

View File

@@ -0,0 +1,47 @@
# 分秒必争
### 题目描述
蒜头君是一个勤奋的好孩子,每天都分秒必争的学习。
已知现在是 `h:m:s` 点,$h$ 表示小时,$m$ 表示分钟,$s$ 表示秒,那么也即现在是一天中的第 $h$ 小时,第 $m$ 分钟,第 $s$ 秒。其中 $0\leq h< 24,0\leq m< 60,0\leq s< 60$。
已知`0:0:0`是一天中的第 $0$ 秒,他想知道现在的时间是这一天中的第几秒。
蒜头君很快就想到了答案,因为 $1m=60s,1h=60m$,那么 $1h=60\times 60=3600s$,也即一分钟有 $60$ 秒,一小时有 $60$ 分钟,那么一小时有 $3600$ 秒,那么答案就是 $3600\times h+60\times m+s$。
现在蒜头君把这个问题抛给了你,你能回答这个问题吗?
### 输入格式
输入三个正整数 $h,m,s$,分别表示小时、分钟、秒。
### 输出格式
输出一个正整数,表示这是今天的第几秒。
### 数据范围
$0\leq h< 24,0\leq m< 60,0\leq s < 60$。
<div style="page-break-after: always"></div>
### 题解
因为 $1m=60s,1h=60m$,那么 $1h=60\times 60=3600s$,也即一分钟有 $60$ 秒,一小时有 $60$ 分钟,那么一小时有 $3600$ 秒,那么答案就是 $3600\times h+60\times m+s$。
#### 参考代码
```c++{.line-numbers}
#include <iostream>
using namespace std;
int main() {
int h, m, s;
cin >> h >> m >> s;
int ans = h * 3600 + m * 60 + s;
cout << ans << endl;
return 0;
}
```
<div style="page-break-after: always"></div>

View File

@@ -0,0 +1,111 @@
### 题目描述
$\text{Mila}$ 种了一棵苹果树,在魔法的浇灌下苹果树茁壮成长,很快就结出了苹果。
但是天有不测风云,一个夜晚,天打五雷轰,苹果树倒了。
在苹果树倒之前,$\text{Mila}$ 忘记记录哪些节点上有苹果了,但是 $\text{Mila}$ 记得,这棵苹果树的根节点是 $1$,并且每个节点上最多有 $1$ 个苹果。在树倒之前 $\text{Mila}$ 记录下了一些数字,$a_i$ 表示 $i$ 号节点的子树内的苹果数量不超过 $a_i$。
现在 $\text{Mila}$ 想要知道,这棵苹果树有多少种可能?由于 $\text{Mila}$ 数学不太好,所以请你帮帮她。
### 输入格式
第一行一个整数 $n$,表示苹果树的节点数量。
第二行 $n$ 个整数,第 $i$ 个整数为 $a_i$。
下面 $n-1$ 行每行两个整数 $x,y$,表示 $x,y$ 节点之间有一条边。
### 输出格式
输出一行一个整数,表示苹果树可能的方案数,答案对 $998244353$ 取模。
### 数据范围
对于 $20\%$ 的数据,满足 $n\leq 20$。
对于 $40\%$ 的数据,满足 $n\leq 100$。
对于另外 $10\%$ 的数据,保证 $a_i\leq 1$。
对于另外 $10\%$ 的数据,保证 $x=1$。
对于 $100\%$ 的数据,满足 $0\leq a_i\leq 2\times 10^3, 1\leq n \leq 2\times 10^3$。
<div style="page-break-after: always"></div>
### 题解
不难想到树形 DP,那么就能够自然地定义出状态:$f_{i,j}$ 表示 $i$ 的子树内放了 $j$ 个苹果的方案数。
转移的时候,考虑 $x$ 的一棵子树 $y$,将 $y$ 的信息和 $x$ 之前的儿子的信息合并起来,可以得到:$$f'_{x,i}=\sum_{j=0}^{sz_y}f_{y,j}f_{x,i-j}$$其中,$sz_y$ 表示 $y$ 的子树大小。
统计完所有儿子后,将自己的 $a_x+1$ 以上的部分清 $0$,因为这部分是不合法的,即让 $f_{x,[a_x+1,n]}=0$。
咋一看这个 DP 是 $O(n^3)$ 的,其实不然,这是 $\text{dp}$ 中的经典套路,仔细思考可以发现这其实是 $O(n^2)$ 的。
证明也不难,合并子树时,$f_{x,i}$ 和 $f_{y,j}$ 乘起来贡献 $f'_{x,i+j}$,不妨换个角度来看,可以看成 $x$ 之前的子树中第 $i$ 个点和 $y$ 的子树中第 $j$ 个点乘起来做贡献。那么仔细观察,其实每个点只会和其他点乘起来贡献一次,贡献的对象就是他们的 $\text{lca}$。所以总共的贡献次数只有 $n^2$ 次。
#### 参考代码
```c++{.line-numbers}
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
const int NMAX = 2100;
const int MOD = 998244353;
vector<int> E[NMAX];
int limit[NMAX], siz[NMAX];
int dp[NMAX][NMAX];
void solve(int x, int fa) {
siz[x] = 1;
dp[x][0] = 1;
if (limit[x] >= 1) {
dp[x][1] = 1;
}
for (auto y: E[x]) {
if (y == fa) {
continue;
}
solve(y, x);
for (int i = siz[x] + siz[y]; i >= 0; i -= 1) {
if (i > limit[x]) {
dp[x][i] = 0;
continue;
}
int j_init = max(i - siz[x], 1);
int j_lim = min(siz[y], i);
for (int j = j_init; j <= j_lim; j += 1) {
(dp[x][i] += (long long )dp[y][j] * dp[x][i - j] % MOD) %= MOD;
}
}
siz[x] += siz[y];
}
}
int main() {
freopen("appletree.in", "r", stdin);
freopen("appletree.out", "w", stdout);
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i += 1) {
scanf("%d", &limit[i]);
}
for (int i = 1; i < n; i += 1) {
int x, y;
scanf("%d %d", &x, &y);
E[x].push_back(y);
E[y].push_back(x);
}
solve(1, -1);
int ans = 0;
for (int i = 0; i <= limit[1] && i <= n; i += 1) {
(ans += dp[1][i]) %= MOD;
}
printf("%d\n", ans);
exit(0);
}
```
<div style="page-break-after: always"></div>

View File

@@ -0,0 +1,88 @@
# Sever the Skyline
### 题目描述
「被废弃的城市」中心有一台「不知所谓的机器」。机器顶端天线上的灯泡隐隐约约地散发着光芒。
云浅发现灯泡每次闪烁后发出的颜色有一定的规律。
具体来说,灯泡每次闪烁后的颜色可以用 $n$ 个二元组 $(a_1,b_1),(a_2,b_2),\cdots,(a_n,b_n)$ 来表示。机器会对每个 $i=1,2,3,\cdots,n$ 闪烁 $a_i$ 次,并且这 $a_i$ 次闪烁发出的颜色都为 $b_i$。
现在云浅想知道,机器第 $m$ 次闪烁后,发出的颜色是什么。
### 输入格式
第一行两个正整数 $n,m$。
第二行 $n$ 个正整数 $a_1,\cdots,a_n$。
第三行 $n$ 个正整数 $b_1,\cdots,b_n$。
### 输出格式
输出一行一个正整数表示答案。
### 数据范围
对于 $100\%$ 的数据,$1\le n\le 10^5,1\le m,a_i,b_i\le 10^9,m\le \sum a_i$。
| 测试点编号 | $n$ | $a_i$ | 其他 |
| :-: | :-: | :-: | :-: |
| $1\sim 3$ | $\le 100$ | $\le 100$ | 无 |
| $4\sim 5$ | $\le 1000$ | $\le 1000$ | 无 |
| $6\sim 8$ | $\le 10^5$ | $\le 10^5$ | $m\le 10^6$ |
| $9\sim 10$ | $\le 10^5$ | $\le 10^9$ | 无 |
<div style="page-break-after: always"></div>
### 题解
找到最小的满足 $a_1+a_2+\cdots+a_k\ge m$ 的 $k$,输出 $b_k$ 即可。
复杂度 $O(n)$。
#### 参考代码
```c++{.line-numbers}
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
for (; (c < '0' || c > '9'); c = getchar()) {
if (c == '-') {
f = -1;
}
}
for (; (c >= '0'&& c <= '9'); c = getchar()) {
x = x * 10 + (c& 15);
}
return x * f;
}
int n, m;
const int MN = 1e5 + 5;
int a[MN], b[MN];
signed main(void) {
freopen("city.in", "r", stdin);
freopen("city.out", "w", stdout);
n = read();
m = read();
int x = 0;
for (int i = 1; i <= n; i++) {
a[i] = read();
}
for (int i = 1; i <= n; i++) {
b[i] = read();
}
for (int i = 1; i <= n; i++) {
x += a[i];
if (x >= m) {
cout << b[i] << endl;
return 0;
}
}
return 0;
}
```
<div style="page-break-after: always"></div>

View File

@@ -0,0 +1,3 @@
入门:https://nanti.jisuanke.com/t/T3705
普及:https://nanti.jisuanke.com/t/T3667
提高:https://nanti.jisuanke.com/t/T3702