A Phone Numbers
题意:定义“电话号码”为开头为‘8’,长度为11的字符串。给定一些字符,每个字符只能用一次,求可以拼出多少个电话号码(可以重复)。
直接min(str.length()/11, number_of_8_in(str))
B Maximum Sum of Digits
题意:设\(S(a)\)为\(a\)的各数位之和,求最大的\(S(a)+S(b)\),满足\(a+b=n\)。
让\(a\)全是\(9\)并且尽可能大就行了(鬼知道为什么)。
C Maximum Subrectangle
题意:给定序列\(A,B\),令矩阵\(C\)满足\(C_{i,j} = A_i B_j\),求\(C\)中元素和不超过\(x\)的最大子矩阵\((1\le len(A), len(B), A_i, B_i \le 2000, x \le 2\cdot 10^9)\)。
D Social Circles
题意:你有一些害♂羞的客人坐在若干个(自定)圆桌旁,他们需要自己左右各有一定数量的椅子,求最少要多少张椅子\((1 \le n \le 10^5)\)。
如果一开始每个人自己坐在一个桌子上,两个人\((a, b), (c, d)\)坐在一起相当于\((a, d), (c, b)\)分开坐。所以我们可以通过交换\(r\)来达到坐在一块的效果,所以,我们让小的\(l\)搭配小的\(r\),就可以算出最优解了。
E Sergey and Subway
题意:给定一棵树,并且连接起距离为2的所有点,求这时的所有点对之间的距离和。
“所有点对之间的距离和”,看到这句话我就想到了以前做过的一个题,直接树形DP就好了,新图中的距离等于\(\lceil dis(i,j)/2\rceil\),但事实上,直接加起来除以2不行的。所以就只能在dfs
的时候顺带计算了,注意到是除以2后上取整,在进入子树的时候有一个奇偶互换的过程,具体实现看代码吧。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
typedef unsigned long long LL;
const int N = 200000+10;
const int M = N<<1;
std::vector<int> g[N];
LL n, tot, ans, sz[N], dep[N], even[N];
void dfs(int x, int f) {
tot += (dep[x] + 1) / 2;
sz[x]++;
even[x] = 1;
for (int i : g[x]) if (i != f) {
dep[i] = dep[x] + 1;
dfs(i, x);
sz[x] += sz[i];
even[f] += even[i];
}
}
void calc(int x, LL to, int f, LL p) {
// p是所有点中到x的距离为偶数的点的个数
// to是当前的答案
ans += to;
for (int i : g[x]) if (i != f) {
// 传递到儿子的时候
// 儿子的子树中的距离儿子为偶数的点的贡献-1
// 儿子的子树外距离儿子为奇数的点的贡献+1
calc(i, to - even[i] + p - sz[i] + even[i], x, n - p);
}
}
int main() {
scanf("%lld", &n);
for (int i = 1, x, y; i < n; ++i) {
scanf("%d%d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1, 0);
calc(1, tot, 0, even[1]);
printf("%lld\n", ans / 2);
return 0;
}
emm,实际上,这个题还有一种更加简便的做法:我们完全可以将新图中的距离和写成\((DistSumOfOldTree+NumberOfOddPath)/2\),原图中的距离可以dfs的时候算(按边算贡献,即边的两侧的点数乘积)。然后长度为奇数的路径条数就是深度为奇数的点的个数乘以深度为偶数的点的个数。
F Shrinking Tree
题意:给定一棵树,每次等可能的选择一条边,将其左右端点合并,合并后的新点的编号是合并之前的两个点之一(等可能),问最后剩下的那个点的编号是\(x\)的可能性\((n \le 50)\)。
G Balls and Pockets
题意:有一个由无限个房间顺次连接构成的区域,每个房间里有一个和房间编号相同的球,其中\(n\)个房间里有一个口袋,定义过滤操作为:将有口袋的房间的球消灭,然后对于每个有球房间,其中的球放入现在编号最小且小于当前房间的空房间,如果没有这样的房间,就不移动这个球。\(m\)次询问第k次过滤后第x个位置上的球的编号\((n,m \le 10^5, x_i, k_i \le 10^9)\)。
H Sophisticated Device
题意:你有无限个存储单元,标号为\(1..\infty\),其中\(1\)号单元存储着数\(x\),二号单元存储着数\(y\),其余单元存储着\(1\),给定如下操作:+ e1 e2 to
表示将单元\(e1\)和\(e2\)中的数的和放入单元\(to\)中,^ e1 e2
表示将单元\(e1\)中的数的\(d\)次方放入\(e2\)中,f e
表示返回单元\(e\)中的值,给定\(d\)和\(p\),你需要设计一个操作序列使得无论\(x,y\)是多少,最后都返回\(xy\)。(以上操作均在模\(p\)意义下,其中\(p\)为质数)\((2 \le d \le 10, 3 \le p \le 10^9 + 9)\)。