怎么BJOI这么多送分题啊
$$ \text{设}f\left( n \right) \text{表示把前}n\text{块玻璃视为一个整体,从第一块玻璃入射的光穿透前}n\text{块玻璃的透光率。} \\ \text{设}g\left( n \right) \text{表示把前}n\text{块玻璃视为一个整体,从第}n\text{块玻璃入射,仍然能从第}n\text{块玻璃射出来的反射率。} \\ \text{显然有}f\left( 1 \right) =a_1,g\left( 1 \right) =b_1 \\ \text{对于}n>\text{1有}f\left( n \right) =\sum_{i\ge 0}{f\left( n-1 \right) \left( g\left( n-1 \right) b_n \right) ^i}a_n\left( \text{枚举光线在}n\text{和}n-\text{1之间的反射次数} \right) \\ =f\left( n-1 \right) a_n\sum_{i\ge 0}{\left( g\left( n-1 \right) b_n \right) ^i}=\frac{f\left( n-1 \right) a_n}{1-g\left( n-1 \right) b_n} \\ g\left( n \right) =b_n+\sum_{i\ge 0}{a_ng\left( n-1 \right) \left( g\left( n-1 \right) b_n \right) ^ia_n}=b_n+\frac{g\left( n-1 \right) a_{n}^{2}}{1-b_ng\left( n-1 \right)} \\ \left( \text{先考虑直接在第}n\text{块反射了的情况,然后枚举在}n\text{和}n-\text{1之间的反射次数} \right) $$
#include <iostream>
using int_t = long long int;
using std::cin;
using std::cout;
using std::endl;
const int_t LARGE = 1e6;
const int_t mod = 1e9 + 7;
constexpr int_t power(int_t base, int_t index) {
int_t result = 1;
index = (index % (mod - 1) + mod - 1) % (mod - 1);
base = (base % mod + mod) % mod;
while (index) {
if (index & 1) result = result * base % mod;
index >>= 1;
base = base * base % mod;
}
return result;
}
const int_t inv100 = power(100, -1);
int main() {
static int_t f[LARGE + 1], g[LARGE + 1], a[LARGE + 1], b[LARGE + 1];
int_t n;
cin >> n;
for (int_t i = 1; i <= n; i++) {
int_t x, y;
scanf("%lld%lld", &x, &y);
a[i] = x * inv100 % mod;
b[i] = y * inv100 % mod;
}
f[1] = a[1], g[1] = b[1];
for (int_t i = 2; i <= n; i++) {
f[i] = (f[i - 1] * a[i] % mod) * power(1 - g[i - 1] * b[i], -1) % mod;
g[i] = (b[i] + (a[i] * a[i] % mod * g[i - 1] % mod *
power(1 - b[i] * g[i - 1] % mod, -1))) %
mod;
}
cout << f[n] << endl;
return 0;
}
发表回复