【矩阵加速】【数学】2019雅礼集训 math

4 篇文章 0 订阅
3 篇文章 0 订阅

题目:

在这里插入图片描述
在这里插入图片描述
简单地说,就是对于n的每一个长度为m的划分( k i > 0 k_i>0 ki>0),求出其贡献的值之和。


分析:

非常神奇的三角函数题:
首先,可以想到,划分问题有一个很经典的DP
定义 D P ( i , j ) DP(i,j) DP(i,j)表示将i划分为j个的方案数。
转移式为: D P ( i , j ) = D P ( i − 1 , j − 1 ) + D P ( i − j , j ) DP(i,j)=DP(i-1,j-1)+DP(i-j,j) DP(i,j)=DP(i1,j1)+DP(ij,j)。即考虑划分状态中存在/不存在1的情况。存在1,则通过去掉那个1转移,不存在1,则通过每一位-1来转移。

考虑将这个DP方式套在这里:
定义 f ( i , j ) f(i,j) f(i,j)表示将n=i,m=j时的答案。
若m项中,存在1,则转移到 f ( i − 1 , j − 1 ) ∗ s i n ( x ) f(i-1,j-1)*sin(x) f(i1,j1)sin(x)

若不存在1,此时不必所有项都-1,只需要某一项-1就能转移了:

首先通过和角公式得到:
s i n ( k i x ) = s i n ( ( k i − 1 ) x ) c o s ( x ) + c o s ( ( k i − 1 ) x ) s i n ( x ) sin(k_ix)=sin((k_i-1)x)cos(x)+cos((k_i-1)x)sin(x) sin(kix)=sin((ki1)x)cos(x)+cos((ki1)x)sin(x)

其中前半部分 s i n ( ( k i − 1 ) x ) sin((k_i-1)x) sin((ki1)x)就是我们要的,但后半部分还不对。

继续运用和角公式:
s i n ( x ) c o s ( ( k i − 1 ) x ) = s i n ( x ) { c o s ( ( k i − 2 ) x ) c o s ( x ) − s i n ( ( k i − 2 ) x ) s i n ( x ) } sin(x)cos((k_i-1)x)=sin(x)\{cos((k_i-2)x)cos(x)-sin((k_i-2)x)sin(x)\} sin(x)cos((ki1)x)=sin(x){cos((ki2)x)cos(x)sin((ki2)x)sin(x)}
s i n ( x ) sin(x) sin(x)乘进去
= s i n ( x ) c o s ( x ) c o s ( ( k i − 2 ) x ) − s i n 2 ( x ) s i n ( ( k i − 2 ) x ) =sin(x)cos(x)cos((k_i-2)x)-sin^2(x)sin((k_i-2)x) =sin(x)cos(x)cos((ki2)x)sin2(x)sin((ki2)x)
因为 s i n 2 ( x ) = 1 − c o s 2 ( x ) sin^2(x)=1-cos^2(x) sin2(x)=1cos2(x)
= c o s ( x ) { s i n ( x ) c o s ( ( k i − 2 ) x ) + c o s ( x ) s i n ( ( k i − 2 ) x ) } − s i n ( ( k i − 2 ) x ) =cos(x)\{sin(x)cos((k_i-2)x)+cos(x)sin((k_i-2)x)\}-sin((k_i-2)x) =cos(x){sin(x)cos((ki2)x)+cos(x)sin((ki2)x)}sin((ki2)x)
显然大括号里面的也是个和角公式。
= c o s ( x ) s i n ( ( k i − 1 ) x ) − s i n ( ( k i − 2 ) x ) =cos(x)sin((k_i-1)x)-sin((k_i-2)x) =cos(x)sin((ki1)x)sin((ki2)x)
综上所述:
s i n ( k i x ) = 2 c o s ( x ) s i n ( ( k i − 1 ) x ) − s i n ( ( k i − 2 ) x ) sin(k_ix)=2cos(x)sin((k_i-1)x)-sin((k_i-2)x) sin(kix)=2cos(x)sin((ki1)x)sin((ki2)x)
换言之:
f ( i , j ) = 2 c o s ( x ) f ( i − 1 , j ) − f ( i − 2 , j ) f(i,j)=2cos(x)f(i-1,j)-f(i-2,j) f(i,j)=2cos(x)f(i1,j)f(i2,j)
再加上之前的存在1的情况。
就是
f ( i , j ) = 2 c o s ( x ) f ( i − 1 , j ) − f ( i − 2 , j ) + f ( i − 1 , j − 1 ) f(i,j)=2cos(x)f(i-1,j)-f(i-2,j)+f(i-1,j-1) f(i,j)=2cos(x)f(i1,j)f(i2,j)+f(i1,j1)
然后,这个就可以矩阵加速了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 100
using namespace std;
int n,m;
double tmp[MAXN][MAXN];
struct Matrix{
	double a[MAXN][MAXN];
	void operator *=(const Matrix & b) {
		for(int i=0;i<3*m;i++)
			for(int j=0;j<3*m;j++)
				tmp[i][j]=0;
		for(int i=0;i<3*m;i++)
			for(int k=0;k<3*m;k++)
				for(int j=0;j<3*m;j++)
					tmp[i][j]+=a[i][k]*b.a[k][j];
		for(int i=0;i<3*m;i++)
			for(int j=0;j<3*m;j++)
				a[i][j]=tmp[i][j];
	}
}res,e;
void fsp(Matrix &x,int y){
	while(y){
		if(y&1)
			res*=x;
		x*=x;
		y>>=1;
	}
}
int t;
int main(){
	SF("%d",&t);
	while(t--){
		double x;
		SF("%d%d%lf",&m,&n,&x);
		memset(res.a,0,sizeof res.a);
		memset(e.a,0,sizeof e.a);
		for(int i=0;i<m;i++){
			e.a[i][i]=2.0*cos(x);
			if(i!=m-1)
				e.a[i+1][i]=sin(x);
			e.a[i+m][i]=-1;
		}
		for(int i=m;i<2*m;i++)
			e.a[i-m][i]=1;
		res.a[0][m-1]=sin(x);
//		for(int i=1;i<n;i++){
//			res*=e;
//			for(int j=0;j<2*m;j++)
//				PF("%lf ",res.a[0][j]);
//			PF("\n");
//		}		
		fsp(e,n-1);
		double ans=res.a[0][0];
//		PF("[%lf]",ans);
		if(ans<0){
			PF("-");
			ans=-ans;
		}
		else
			PF("+");
		while(ans>=10.0)
			ans/=10.0;
		while(ans*10.0<10.0)
			ans*=10.0;
		PF("%d\n",int(ans));
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值