BJOI 2019 光线 题解

题目传送门

题目大意: n n n 层玻璃叠在一起,第 i i i 层的透光率和折射率分别为 a i , b i a_i,b_i ai,bi,求从第 1 1 1 层摄射入 1 1 1 单位光最后有多少能穿过全部玻璃。

题解

答案其实就是 n n n 层玻璃总的透光率,这启示我们多层玻璃是有总透光率的,那么就可以考虑递推。

f i f_i fi 表示前 i i i 层玻璃从上往下射一束光线的总透光率,手玩一下就发现还需要求出从下往上射一束光线的总反射率才能递推,将其设为 g i g_i gi

考虑从上一层射过来了 f i − 1 f_{i-1} fi1 的光线,有多少能穿过第 i i i 层,有:
f i = f i − 1 a i ∑ j = 0 ∞ ( b i g i − 1 ) j f_i=f_{i-1}a_i\sum_{j=0}^{\infty}(b_ig_{i-1})^j fi=fi1aij=0(bigi1)j

其中枚举的 j j j 就是光线在 i i i i − 1 i-1 i1 层间反复横跳的次数,每横跳一次光线就衰减为原来的 b i g i − 1 b_ig_{i-1} bigi1

发现里面是个等比数列求和,所以有:
f i = f i − 1 a i × 1 1 − b i g i − 1 f_i=f_{i-1}a_i\times \frac 1 {1-b_ig_{i-1}} fi=fi1ai×1bigi11

类似的,可以得到 g g g 的递推式:
g i = b i + a i 2 g i − 1 ∑ j = 0 ∞ ( b i g i − 1 ) j = b i + a i 2 g i − 1 × 1 1 − b i g i − 1 g_i=b_i+a_i^2g_{i-1}\sum_{j=0}^{\infty}(b_ig_{i-1})^j=b_i+a_i^2g_{i-1}\times \frac 1 {1-b_ig_{i-1}} gi=bi+ai2gi1j=0(bigi1)j=bi+ai2gi1×1bigi11

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 1000000007

int n,f,g,cur=0;
int ksm(int x,int y){
    
    int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;}
const int inv100=ksm(100,mod-2);

int main()
{
    
    
	scanf("%d",&n);f=1;g=0;
	for(int i=1,a,b,p;i<=n;i++){
    
    
		scanf("%d %d",&a,&b);
		a=1ll*a*inv100%mod;b=1ll*b*inv100%mod; 
		p=ksm(1-1ll*b*g%mod+mod,mod-2);
		f=1ll*f*a%mod*p%mod;
		g=(b+1ll*a*a%mod*g%mod*p%mod)%mod;
	}
	printf("%d",f);
}

猜你喜欢

转载自blog.csdn.net/a_forever_dream/article/details/113648936