CF1970E2 Trails (Medium) 题解
点这里前往游记。
考虑 E1 做法,此时
边界条件
考虑 E2 做法,此时
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef vector<vector<int> > matrix;
const int p=1e9+7;
inline void add(int &x,int y){
if((x+=y)>=p)x-=p;
} // 模意义下的加法,比 (x+=y)%=p 快很多
matrix operator *(matrix &a,matrix &b){
matrix c(a.size(),vector<int>(b[0].size()));
for(int i=0;i<a[0].size();i++)
for(int j=0;j<a.size();j++)
for(int k=0;k<b[0].size();k++)
add(c[j][k],a[j][i]*b[i][k]%p);
return c;
} // 矩阵乘法
main(){
ios::sync_with_stdio(false);
int m,n,c=0; cin>>m>>n;
vector<int> s(m),l(m);
for(auto &i:s)cin>>i;
for(auto &i:l)cin>>i;
matrix a(m,vector<int>(m)),b=a,w(1,vector<int>(m));
for(int i=0;i<m;i++)
for(int j=0;j<m;j++)
b[i][j]=(i==j),a[i][j]=((s[i]+l[i])*s[j]%p+s[i]*l[j]%p)%p;
w[0][0]=1;
while(n){
if(n&1)b=b*a;
a=a*a,n>>=1;
} // 进行矩阵快速幂
w=w*b;
for(auto i:w)for(int j:i)add(c,j); // 统计答案
cout<<c<<endl;
return 0;
}