蓝题都做不出来,我真的是菜到一定境界了。
Description
Solution
首先,我们先将 a , b a,b a,b 分别变为 a 100 \frac {a} {100} 100a 和 b 100 \frac b {100} 100b 在模 1 0 9 + 7 10^9+7 109+7 意义下的值,并令 x = a + b x=a+b x=a+b。
可以发现,答案来源于下面这三个部分的贡献:
①跳到了第
i
i
i 个位置但没有跳到中心,有
1
1
1 的贡献;
②跳到了第
i
i
i 个位置且跳到了中心,也有一定的贡献;
③跳到了第
i
i
i 个关键点
x
i
x_i
xi 的中心,有
y
i
y_i
yi 的贡献。
Part 1
先考虑 ①。
我们枚举 i i i,并求出此事件发生的概率。不难发现,这个概率就是,前 i − 1 i-1 i−1 次都不能跳到地上,且第 i i i 次一定要跳到中心旁边的概率,即 x i − 1 b x^{i-1} b xi−1b。
∑ i = 1 n x i − 1 a = a ∑ i = 0 n − 1 x i = a x n − x 0 x − 1 \begin{aligned} \sum_{i=1}^n x^{i-1} a &= a \sum_{i=0}^{n-1} x^i \\ &= a\frac {x^{n}-x^0} {x-1} \end{aligned} i=1∑nxi−1a=ai=0∑n−1xi=ax−1xn−x0
采用快速幂+逆元计算即可。
哎,等等,如果 x ≡ 1 ( m o d 1 0 9 + 7 ) x \equiv 1 \pmod {10^9+7} x≡1(mod109+7) 怎么办?这时分母为 0 0 0,还算个锤子 ⋯ ⋯ \cdots \cdots ⋯⋯
考虑将 x ≡ 1 x \equiv 1 x≡1 带入原式子,有
∑ i = 1 n 1 i − 1 a = a n \sum_{i=1}^n 1^{i-1}a=an i=1∑n1i−1a=an
特判一下这个情况就好了。
真的好了吗?如果 x ≡ 0 x \equiv 0 x≡0,那么 x 0 x^0 x0 是多少?
于是还要特判 x = 0 x=0 x=0 的情况,此时原式等于 0 0 0。
Part 2
枚举关键点 x i x_i xi,并计算出其产生 y i y_i yi 贡献的概率。
不难发现,这个概率就是,成功跳到 x i − 1 x_i-1 xi−1 且跳到 x i x_i xi 的中心的概率,即 x x i − 1 b x^{x_i-1} b xxi−1b。
∑ i = 1 m x x i − 1 b \sum_{i=1}^m x^{x_i-1} b i=1∑mxxi−1b
枚举+快速幂计算即可,复杂度 O ( m log n ) O(m \log n) O(mlogn)。
Part 3
令 f i f_i fi 表示,跳到第 i i i 个位置的期望 c n t cnt cnt,则这一部分的贡献是
∑ i = 1 n f i − 1 b = b ( ∑ i = 0 n − 1 f i ) \sum_{i=1}^n f_{i-1} b=b\left(\sum_{i=0}^{n-1} f_i\right) i=1∑nfi−1b=b(i=0∑n−1fi)
考虑通过递推计算出各个 f f f。
对于 f i f_i fi 而言,其有两种选择,一是继承 i − 1 i-1 i−1 的 c n t cnt cnt,一是跳到中心旁边将 c n t cnt cnt 更新为 2 2 2。对于前者,其发生的概率为 b b b,贡献为 2 f i − 1 2 f_{i-1} 2fi−1;对于后者,其发生的概率为 a × x i − 1 a \times x^{i-1} a×xi−1,贡献为 2 2 2。因此有
f i = 2 b f i − 1 + 2 a x i − 1 f_i=2bf_{i-1}+2ax^{i-1} fi=2bfi−1+2axi−1
令
g i = ∑ j = 1 i − 1 f i h i = x i g_i=\sum_{j=1}^{i-1} f_i \\ h_i=x^{i} gi=j=1∑i−1fihi=xi
则
f i = ( 2 b ) f i − 1 + ( 2 a ) h i − 1 f_i=(2b)f_{i-1}+(2a)h_{i-1} fi=(2b)fi−1+(2a)hi−1 g i = g i − 1 + f i − 1 g_i=g_{i-1}+f_{i-1} gi=gi−1+fi−1 h i = x h i − 1 h_i=xh_{i-1} hi=xhi−1
写成矩阵乘法的形式
[ f i − 1 g i − 1 h i − 1 ] × [ 2 b 1 0 0 1 0 2 a 0 x ] = [ f i g i h i ] \begin{bmatrix} f_{i-1} \ g_{i-1} \ h_{i-1}\end{bmatrix} \times \begin{bmatrix}2b \ 1 \ 0 \\ 0 \ 1 \ 0 \\ 2a \ 0 \ x\end{bmatrix}=\begin{bmatrix} f_i \ g_i \ h_i\end{bmatrix} [fi−1 gi−1 hi−1]×⎣⎡2b 1 00 1 02a 0 x⎦⎤=[fi gi hi]
更进一步的
[ 2 0 1 ] × ( [ 2 b 1 0 0 1 0 2 a 0 x ] ) n + 1 = [ f n g n + 1 h n + 1 ] \begin{bmatrix} 2 \ 0 \ 1\end{bmatrix} \times \left(\begin{bmatrix}2b \ 1 \ 0 \\ 0 \ 1 \ 0 \\ 2a \ 0 \ x\end{bmatrix}\right)^{n+1}=\begin{bmatrix} f_{n} \ g_{n+1} \ h_{n+1}\end{bmatrix} [2 0 1]×⎝⎛⎣⎡2b 1 00 1 02a 0 x⎦⎤⎠⎞n+1=[fn gn+1 hn+1]
其中 g n g_{n} gn 即为这一部分对答案的贡献。
总复杂度 O ( 3 3 log n + m log n + log mod ) O(3^3 \log n+m \log n+\log \text{mod}) O(33logn+mlogn+logmod),本题被解决。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7,maxl=100005;
int read(){
int s=0,w=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') w=-w;ch=getchar();}
while (ch>='0'&&ch<='9'){s=s*10+(ch^'0');ch=getchar();}
return s*w;
}
int n,a,b,m,res1,res2,res3,ans;
int x[maxl],y[maxl];
struct Matrix{
int ma[3][3];
}base;
Matrix operator * (const Matrix x,const Matrix y){
Matrix z;
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
z.ma[i][j]=0;
for (int k=0;k<3;k++)
z.ma[i][j]=(z.ma[i][j]+x.ma[i][k]*y.ma[k][j])%mod;
}
}
return z;
}
Matrix matrix_quick_power(Matrix x,int y){
Matrix res=x;y--;
for (;y;y=y>>1,x=x*x){
if (y&1) res=res*x;
}
return res;
}
int quick_power(int x,int y){
int res=1;
for (;y;y=y>>1,x=(x*x)%mod){
if (y&1) res=(res*x)%mod;
}
return res;
}
int ny(int tmpx){return quick_power(tmpx,mod-2);}
void calc1(){
int val=(a+b)%mod;
if (val>1)
res1=((quick_power(val,n)-1)*ny(val-1))%mod;
else if (val==1) res1=n%mod;
else res1=0;
res1=(res1*a)%mod;
}
void init3(){
base.ma[0][0]=(2*b)%mod;
base.ma[0][1]=1;
base.ma[0][2]=0;
base.ma[1][1]=1;
base.ma[2][0]=(2*a)%mod;
base.ma[2][2]=(a+b)%mod;
}
void calc3(){
Matrix tmp=matrix_quick_power(base,n);
int tmp_01=tmp.ma[0][1],tmp_02=tmp.ma[2][1];
res3=(tmp_01*2+tmp_02)%mod;
res3=(res3*b)%mod;
}
signed main(){
n=read(),a=read(),b=read(),m=read();
a=(a*ny(100))%mod;b=(b*ny(100))%mod;
for (int i=1;i<=m;i++){
x[i]=read(),y[i]=read();
res2=(res2+quick_power(a+b,x[i]-1)*b%mod*y[i])%mod;
}
calc1(),init3(),calc3();
ans=(res1+res2+res3)%mod;
cout<<ans<<endl;
return 0;
}