这是一道bjoi
但是,他害我费了一个小时时间才AC
作为第一个AC keda里这道题的人 直接教学!!
-
-
说实话,一读题第一反应竟是“bjoi就这?”但是,看完样例的分析我傻了,是我理解错题意了······赶紧从头又分析了一遍,感觉没问题了,便开始敲代码,结果敲了半个小时发现,好像还没有完全理解,再一次回头分析了一下样例(这提醒我们,一定要审好题,理解题意后在动手,要不然就会像我一样,浪费时间),发现第一面和最后一面的反射率是不一样的,我竟然还天真的认为反射率是一样的,不过透光率是一样的(经过计算可知),所以呢,这样就很容易了,只需要维护两个变量即可:
1、光从第 1 面玻璃射入时的透光率。
2、光从第 i 面玻璃射入时的反射率。
��=��−1��∑�=0∞(��−1��)�pi=pi−1ai∑k=0∞(qi−1bi)k
��=��+��−1��2∑�=0∞(��−1��)�qi=bi+qi−1ai2∑k=0∞(qi−1bi)k
其中,还可以进一步优化:带有**∑�=0∞��∑k=0∞ak的形式,当∣�∣∣a∣<1时,它等于11−�1−a1**
所以:
��=��−1��1−��−1��Pi=1−Qi−1biPi−1ai
��=��+��−1��21−��−1��Qi=bi+1−Qi−1biQi−1ai2
可以先计算出**11−��−1��1−Qi−1bi1**简化计算
最后,贴上代码:
-
#include<bits/stdc++.h>
#define N 1000010
#define int long long
#define INF 0x3f3f3f3f
const int Mod = 1e9 + 7;
const int Inv100 = 570000004;//(pow(100, Mod - 2));
#define ld long double
#define M 1010
#define R register int
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*=f;
}inline void write(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
int n;
int p, q;//p:前 i 面玻璃按顺序叠在一起后,光从第 1 面玻璃射入时的透光率。
//q:前 i 面玻璃按顺序叠在一起后,光从第 i 面玻璃射入时的反射率。
inline int Inv(int x){
int a = 1;
for (int i = Mod - 2; i; i >>= 1){
if(i&1) a = a * x % Mod;
x = x * x % Mod;
}
return a;
}
signed main(){
n = read();
p = 1, q = 0;
while(n--){
int a = read(), b = read();
a = a * Inv100 % Mod;
b = b * Inv100 % Mod;
int d = Inv(1 - q * b % Mod + Mod) % Mod;
q = (b + a * a % Mod * q % Mod * d) % Mod;
p = p * a % Mod * d % Mod;
}
write(p);
return 0;
}
-