标签:tchar uil 题解 lan limits sign 代码 long mat
这题首先我们可以推出递推式:
我们先把加数个数大于等于 \(2\) 的限制去掉,最后再减回去即可。
暴力代码:
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T& FF){
FF=0;T RR=1;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH==‘-‘)RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int f[100010];
int main(){int T;read(T);while(T--){
int n;read(n);
f[0]=1;
for(int i=1;i<=n;i++){
f[i]=0;
for(int j=1;j<=i;j++)
f[i]+=j*f[i-j];
}
cout<<f[n]-n<<endl;}
return 0;
}
然后我们看这个东西怎么矩乘。
我们来做差。
我们把这个东西叫做 \(g_{i-1}\)
那么,现在矩阵乘法要做的事情就是利用 \(f_{i-1}\) 和 \(g_{i-1}\) 求出 \(f_i\),我们发现 \(f_i=f_{i-1}+g_{i-1}\),故可得矩阵:
然后我们可以得到:
用矩乘算一下即可。
\(code\):
#include <bits/stdc++.h>
#define int long long
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH==‘-‘)RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
const int N=5,MOD=1000000007;
struct Matrix{
int a[N][N],n,m;
Matrix(){
memset(a,0,sizeof(a));
}
void build(){
for(int i=1;i<=2;i++)a[i][i]=1;
}
}a,ans;
Matrix operator*(const Matrix x,const Matrix y){
Matrix ans;
ans.n=x.m;
ans.m=y.n;
for(int k=1;k<=x.m;k++)
for(int i=1;i<=x.n;i++)
for(int j=1;j<=y.m;j++)
ans.a[i][j]=(ans.a[i][j]+1ll*x.a[i][k]*y.a[k][j]%MOD)%MOD;
return ans;
}
Matrix pw(Matrix a,int k){
Matrix ans;ans.n=ans.m=2;ans.build();
for(;k;k>>=1,a=a*a)
if(k&1)ans=ans*a;
return ans;
}
signed main(){
int T;read(T);
while(T--){
int n;read(n);
Matrix a,b;
a.n=2;a.m=2;
a.a[1][1]=a.a[1][2]=a.a[2][1]=1;a.a[2][2]=2;
b.n=2;b.m=1;
b.a[1][1]=0;b.a[2][1]=1;
a=pw(a,n);
a=a*b;
cout<<(a.a[1][1]-n+MOD)%MOD<<endl;
}
return 0;
}
题解 SP6286 【SUMMUL - Sum of products】
标签:tchar uil 题解 lan limits sign 代码 long mat
原文地址:https://www.cnblogs.com/zhaohaikun/p/14218780.html