「BJOI 2019」光线

传送门


problem

当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收。

设对于任意 x x x,有 x × a i % x\times a_i\% x×ai% 单位的光会穿过它,有 x × b i % x\times b_i\% x×bi% 的会被反射回去。

现在 n n n 层玻璃叠在一起,有 1 1 1 单位的光打到第 1 1 1 层玻璃上,那么有多少单位的光能穿过所有 n n n 层玻璃呢?

数据范围: n ≤ 5 × 1 0 5 n≤5×10^5 n5×105


solution

参考博客

由于第 n n n 层的玻璃也有透光率, n n n 层玻璃也可以看做 1 1 1 层,所以我们试着以合并玻璃的角度思考。

如果我们将 ( a 1 , b 1 ) (a_1,b_1) (a1,b1) ( a 2 , b 2 ) (a_2,b_2) (a2,b2) 两块玻璃合并,考虑得到的新玻璃 ( A , B ) (A,B) (A,B)

注:先说明一点,前 i i i 块复合玻璃的反射率不是从 1 1 1 射入时的反射率,而是从 i i i 射入的反射率。

A = a 1 a 2 ∑ i = 0 ∞ ( b 1 b 2 ) i = a 1 a 2 1 − b 1 b 2 B = b 2 + a 2   2 b 1 ∑ i = 0 ∞ ( b 1 b 2 ) i = b 2 + a 2   2 b 1 1 − b 1 b 2 \begin{aligned}A&=a_1a_2\sum_{i=0}^{\infty}(b_1b_2)^i=\frac{a_1a_2}{1-b_1b_2}\\B&=b_2+a_2^{\,2}b_1\sum_{i=0}^{\infty}(b_1b_2)^i=b_2+\frac{a_2^{\,2}b_1}{1-b_1b_2}\end{aligned} AB=a1a2i=0(b1b2)i=1b1b2a1a2=b2+a22b1i=0(b1b2)i=b2+1b1b2a22b1

推导过程可以找规律,我就不写了。

两两合并后,最后的答案就是 A A A

时间复杂度 O ( n ) O(n) O(n)


code

#include<bits/stdc++.h>
#define N 500005
#define P 1000000007
using namespace std;
int n,a[N],b[N];
int add(int x,int y)  {return x+y>=P?x+y-P:x+y;}
int dec(int x,int y)  {return x-y< 0?x-y+P:x-y;}
int mul(int x,int y)  {return 1ll*x*y%P;}
int power(int a,int b){
	int ans=1;
	for(;b;b>>=1,a=mul(a,a))  if(b&1)  ans=mul(ans,a);
	return ans;
}
int main(){
	scanf("%d",&n);
	int inv=power(100,P-2);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&a[i],&b[i]);
		a[i]=mul(a[i],inv),b[i]=mul(b[i],inv);
	}
	int A=a[1],B=b[1];
	for(int i=2;i<=n;++i){
		int Inv=power(dec(1,mul(B,b[i])),P-2);
		B=add(b[i],mul(mul(mul(a[i],a[i]),B),Inv));
		A=mul(mul(A,a[i]),Inv);
	}
	printf("%d\n",A);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值