题目
题目描述
当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收。
设对于任意 xx,有 x \times a_i%x×a
i
% 单位的光会穿过它,有 x \times b_i%x×b
i
% 的会被反射回去。
现在 nn 层玻璃叠在一起,有 11 单位的光打到第 11 层玻璃上,那么有多少单位的光能穿过所有 nn 层玻璃呢?
输入格式
第一行一个正整数 nn,表示玻璃层数。
接下来 nn 行,每行两个非负整数 a_i,b_ia
i
,b
i
,表示第 ii 层玻璃的透光率和反射率。
输出格式
输出一行一个整数,表示穿透所有玻璃的光对 10^9 + 710
9
+7 取模的结果。
可以证明,答案一定为有理数。设答案为 a/ba/b ( aa 和 bb 是互质的正整数),你输出的答案为 xx,你需要保证 a\equiv bx \space (\text{mod }10^9 + 7)a≡bx (mod 10
9
+7)。
输入输出样例
输入 #1复制
2
50 20
80 5
输出 #1复制
858585865
输入 #2复制
3
1 2
3 4
5 6
输出 #2复制
843334849
说明/提示
样例1解释:
如图,光线从左上角打进来,有 0.50.5 单位的光穿过第 11 层玻璃,有 0.20.2 单位的光被反射回去。这 0.50.5 单位的光有 0.40.4 单位穿过第 22 层玻璃,有 0.0250.025 单位的光被反射回去。这 0.0250.025 单位的光有 0.01250.0125 单位穿过第 11 层玻璃,有 0.0050.005 单位的光被反射回去。这 0.0050.005 单位的光有 0.0040.004 单位穿过第 22 层玻璃……于是,穿过两层玻璃的光一共有0.40404… = 40/990.40404…=40/99 单位。在模 10^9+710
9
+7 意义下等于 858585865858585865。
数据范围:
对于 5%5% 的数据,n=1n=1;
对于 20%20% 的数据,n\le 2n≤2;
对于 30%30% 的数据,n\le 3n≤3;
对于 50%50% 的数据,n\le 100n≤100;
对于 70%70% 的数据,n\le 3000n≤3000;
对于 100%100% 的数据,n\le 5\times 10^5n≤5×10
5
,1\le a_i \le 1001≤a
i
≤100,0\le b_i \le 990≤b
i
≤99,1\le a_i+b_i \le 1001≤a
i
+b
i
≤100。
每组 a_ia
i
和 b_ib
i
在满足上述限制的整数中随机生成。
思路
我们设
d
p
i
dp_i
dpi表示经过
1
1
1单位的光经过前
i
i
i面镜子后变成了多少,也就是前
i
i
i面镜子整体的透光率
设
f
i
f_i
fi表示倒着(即从第
i
i
i面镜子到第
1
1
1面镜子)射入
1
1
1单位的光,反射出去的光为多少,或者说是这
i
i
i面镜子整体的反光率
我们考虑如何求出
d
p
i
dp_i
dpi和
f
i
f_i
fi
先考虑
d
p
i
dp_i
dpi
首先有
d
p
i
−
1
dp_{i-1}
dpi−1的光直接过来了,这些光有
a
i
a_i
ai直接穿过,为
d
p
i
−
1
×
a
i
dp_{i-1}\times a_i
dpi−1×ai
还有
b
i
b_i
bi被反射回去,也就是是有
d
p
i
−
1
×
b
i
dp_{i-1}\times b_i
dpi−1×bi的光倒着穿过了前
i
i
i面镜子,反射回来的光是
d
p
i
−
1
×
b
i
×
f
i
−
1
dp_{i-1}\times b_i\times f_{i-1}
dpi−1×bi×fi−1,这些光又有
a
i
a_i
ai穿过第
i
i
i面镜子
如果往下继续写,我们会发现得到这样一个柿子
d
p
i
=
a
i
∑
j
=
0
∞
d
p
i
−
1
(
f
i
−
1
b
i
)
j
dp_{i}=a_i\sum_{j=0}^{\infty}dp_{i-1}(f_{i-1}b_i)^j
dpi=aij=0∑∞dpi−1(fi−1bi)j
对后面求一下和
d
p
i
=
a
i
×
d
p
i
−
1
1
−
f
i
−
1
b
i
dp_{i}=\frac{a_i\times dp_{i-1}}{1-f_{i-1}b_i}
dpi=1−fi−1biai×dpi−1
再来考虑
f
i
f_i
fi
首先有
1
1
1的光射了过来,有
b
i
b_i
bi直接被反射回去,这里是
b
i
b_i
bi
但是有
a
i
a_i
ai的光射了进去,所以有
f
i
−
1
×
a
i
f_{i-1}\times a_i
fi−1×ai的光被反射回来,这些光在经过第
i
i
i面镜子,反射出来的是
f
i
−
1
×
a
i
2
f_{i-1}\times a_i^2
fi−1×ai2
继续往下写,我们得到了这样的柿子
f
i
=
b
i
+
∑
j
=
0
∞
a
i
2
f
i
−
1
(
f
i
−
1
b
i
)
j
=
b
i
+
f
i
−
1
×
a
i
2
1
−
f
i
−
1
b
i
f_i=b_i+\sum_{j=0}^{\infty}a_i^2f_{i-1}(f_{i-1}b_i)^j=b_i+\frac{f_{i-1}\times a_{i}^2}{1-f_{i-1}b_i}
fi=bi+j=0∑∞ai2fi−1(fi−1bi)j=bi+1−fi−1bifi−1×ai2
于是我们递推就好了,答案就是
d
p
n
dp_n
dpn
代码
#include<bits/stdc++.h>
#define MAXN 500005
#define reg register
#define inl inline
#define int long long
using namespace std;
const int Mod=1e9+7;
int n,a[MAXN],b[MAXN],f[MAXN],g[MAXN];
inl int Add(reg int x,reg int y)
{
return x+y>Mod?x+y-Mod:x+y;
}
inl int Dec(reg int x,reg int y)
{
return x-y<0?x-y+Mod:x-y;
}
inl int Mul(reg int x,reg int y)
{
return x*y-x*y/Mod*Mod;
}
inl int Pow(reg int x,reg int y)
{
reg int res=1;
for(;y;y>>=1,x=Mul(x,x)) if(y&1) res=Mul(res,x);
return res;
}
signed main()
{
reg int inv=Pow(100,Mod-2);
scanf("%lld",&n);
for(reg int i=1;i<=n;i++)
{
scanf("%lld %lld",&a[i],&b[i]);
a[i]=Mul(inv,a[i]);
b[i]=Mul(inv,b[i]);
}
f[0]=1;
for(reg int i=1;i<=n;i++)
{
reg int p=Pow(Dec(1,Mul(g[i-1],b[i])),Mod-2);
f[i]=Mul(Mul(f[i-1],a[i]),p);
g[i]=Add(b[i],Mul(Mul(Mul(g[i-1],a[i]),a[i]),p));
}
printf("%lld\n",f[n]);
return 0;
}