码迷,mamicode.com
首页 > 其他好文 > 详细

题解 SP6286 【SUMMUL - Sum of products】

时间:2021-01-05 10:41:20      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tchar   uil   题解   lan   limits   sign   代码   long   mat   

这题首先我们可以推出递推式:

我们先把加数个数大于等于 \(2\) 的限制去掉,最后再减回去即可。

\[f_0=1 \]

\[f_n=\sum\limits_{i=1}^{n} j \cdot f_{i-j} \]

暴力代码:

#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;
}

然后我们看这个东西怎么矩乘。

我们来做差。

\[\begin{aligned}f_n-f_{n-1}&=\sum\limits_{i=1}^{n} j \cdot f_{i-j}-\sum\limits_{i=1}^{n-1} j \cdot f_{i-j-1}\\&=f_{i-1}+2\cdot f_{i-2}+\cdots + i\cdot f_{0}-[f_{i-2}+2\cdot f_{i-3}+\cdots + (i-1)\cdot f_{0}]\\&=f_{i-1}+f_{i-2}+\cdots+f_{0}\end{aligned} \]

我们把这个东西叫做 \(g_{i-1}\)

那么,现在矩阵乘法要做的事情就是利用 \(f_{i-1}\)\(g_{i-1}\) 求出 \(f_i\),我们发现 \(f_i=f_{i-1}+g_{i-1}\),故可得矩阵:

\[\begin{bmatrix}1&1\\1&2\\\end{bmatrix}\begin{bmatrix}f_{i-1}\\g_{i-1}\end{bmatrix}=\begin{bmatrix}f_{i}\\g_{i}\end{bmatrix} \]

然后我们可以得到:

\[\begin{bmatrix}0\\1\end{bmatrix}\begin{bmatrix}1&1\\1&2\end{bmatrix}^n \]

用矩乘算一下即可。

\(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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!