abc151
题解翻译器 2022-4-28
A题
过于简单,不解
B题
过于简单,不解
C题
过于简单,不解
D题
以每个点为起点,bfs即可。(但是似乎没说有没有无法到达的情况)
E题
暴力是 O ( n 2 ) O(n^2) O(n2) 的,显然不能通过。
仍然是反过来考虑,考虑每个值的贡献,首先排序,然后我们考虑每个值 a i a_i ai 分别做 m a x max max 和 m i n min min 时的贡献即可,这是一个简单的组合问题,每个数会做 ( i − 1 k − 1 ) i-1 \choose k-1 (k−1i−1) 次的 m a x max max, ( n − i k − 1 ) n-i \choose k - 1 (k−1n−i) 次的 m i n min min,加上贡献即可。
给一个线性组合数板子,调用一次 init()
初始化,然后就可以 c(n,m)
得到组合数了。
const int MOD = 1e9+7;
const int lim = 2e5+100;
int fc[lim], rfc[lim];
int qp(int x,int p = MOD - 2)
{
int res = 1;
while (p)
{
if (p & 1) res = 1ll * x * res % MOD;
p >>= 1;
x = 1ll * x * x % MOD;
}
return res;
}
void init()
{
fc[0] = 1;
for (int i = 1; i < lim; ++i)
fc[i] = 1ll * fc[i - 1] * i % MOD;
rfc[lim - 1] = qp(fc[lim - 1]);
for (int i = lim - 1; i > 0; --i)
rfc[i - 1] = 1ll * rfc[i] * i % MOD;
}
int C(int n,int m)
{
if (n < m || m < 0) return 0;
return 1ll * fc[n] * rfc[m] % MOD * rfc[n - m] % MOD;
}
E题
找一个最小的半径圆包含所有点。
提供两种思路:
solve1
我们考虑圆心的位置 ( x , y ) (x,y) (x,y),那么对于函数 f ( x , y ) f(x,y) f(x,y) 表示以 ( x , y ) (x,y) (x,y) 为圆心的包含所有点的最小半径。按理来说,存在唯一最小值。
考虑模拟退火。但是我退火失败了,希望网友来个好的模拟退火板子。
solve2
中规中矩的做法。
考虑二分半径,如何 c h k chk chk 呢?显然对于每一个符合要求的圆,一定有两个点在圆上,我们枚举这两个点,通过三角形求出圆心(两个),然后通过圆心检查即可,复杂度 O ( n 3 log R ) O(n^3 \log R) O(n3logR)
暂时每找到其他优雅的做法。