「EZEC-6」跳一跳 题解
P0:题外话
这题其实还可以推式子,这里也不再赘述了。
P1:题解
预处理
先用逆元把百分号处理了:
下文中为了简便,
再把特殊格处理掉。
按照题目意思,额外加到特殊格
故可以预先算出所有特殊格的期望得分之和,即
\text{Subtask 1}
小 A 有
时间复杂度
int main(){
cin>>n>>a>>b>>m;
if (m) cin>>x>>y;
cout<<(3 + y) * qp(2,mod - 2) % mod;
return 0;
}
\text{Subtask 2, 3}
深搜即可,不再赘述。
时间复杂度
void dfs(ll x,ll y,ll z){
if (x > n) return;
ans2 = (ans2 + y * z % mod) % mod;
dfs(x + 1,1,z * a % mod),dfs(x + 1,(y ? 2 * y % mod : 2),z * b % mod);
}
\text{Subtask 4, 5}
除去特殊格的额外加分,令
发现每个
易推得
进而
最终答案为
int main(){
n = read(),a = read(),b = read(),m = read(),init();
for (ll i = 0;i < m;i += 1){
x = read(),y = read();
ans = (ans + qp(a + b,x - 1) * b % mod * y % mod) % mod;
}
for (ll i = 1;i <= n;i += 1){
f[i] = ((a + b) * f[i - 1] % mod + a * bb % mod) % mod;
bb = 2 * b * bb % mod;
s[i] = (s[i - 1] + f[i] + bb) % mod;
}
cout<<(s[n] + ans) % mod;
return 0;
}
\text{Subtask 6}
易得答案为
\text{Subtask 7}
易得答案为
\text{Subtask 8, 9}
矩阵优化下前面的递推式即可。
构造矩阵:
其中
答案为
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,a,b,x,y,ans,hx = 57e7 + 4,mod = 1e9 + 7;
struct st{ll m[5][5];}ma,mb;
inline ll read(){
ll s = 0,w = 1;
char ch = getchar();
while (ch < '0'|| ch > '9'){ if (ch == '-') w = -1; ch = getchar();}
while (ch >= '0'&& ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48),ch = getchar();
return s * w;
}
ll qp(ll x,ll y){
if (!y) return 1;
ll p = qp(x,y / 2);
if (y & 1) return p * p % mod * x % mod;
return p * p % mod;
}
st calc(st a,st b){
st res; fill(res.m[0],res.m[0] + 5 * 5,0);
for (int i = 1;i <= 4;i += 1)
for (int j = 1;j <= 4;j += 1)
for (int k = 1;k <= 4;k += 1)
res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
return res;
}
ll qpmx(ll p){
while (p){
if (p & 1) ma = calc(ma,mb);
mb = calc(mb,mb),p >>= 1;
}
return ma.m[1][1];
}
void init(){
a = a * hx % mod,b = b * hx % mod;
ma.m[1][2] = a,ma.m[1][3] = a * b % mod * 2 % mod,ma.m[1][4] = 2 * b % mod;
mb.m[1][1] = mb.m[2][1] = mb.m[4][1] = mb.m[3][2] = 1;
mb.m[2][2] = (a + b) % mod,mb.m[3][3] = mb.m[4][4] = 2 * b % mod;
}
int main(){
n = read(),a = read(),b = read(),m = read(),init();
for (ll i = 0;i < m;i += 1){
x = read(),y = read();
ans = (ans + qp(a + b,x - 1) * b % mod * y % mod) % mod;
}
cout<<(qpmx(n) + ans) % mod;
return 0;
}