洛谷P1313 计算系数

题目描述

给定一个多项式(by+ax)^k,请求出多项式展开后x^n y^m项的系数。

输入格式

共一行,包含55个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。

输出格式

共1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对1000710007 取模后的结果。

输入输出样例

输入 #1
1 1 3 1 2
输出 #1
3

说明/提示

【数据范围】

对于30% 的数据,有0 ≤k ≤10

对于50%的数据,有a = 1,b = 1

对于100%的数据,有0k1,000,0n,mk,且n+m=k ,0 ≤a,b ≤1,000,000。

noip2011提高组day2第1题

思路很简单,就是杨辉三角,但是有所不同的是,要根据不同的a,b来选择不同的系数,比如说ax+by的k次方中,x的n次方乘以y的m次方就是a的n次方乘以b的m次方然后再模10007,但是这个数据范围显然太大了,所以要用到快速幂,就可以AC了。至于杨辉三角,我用了一个dp来解决

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
long long ksm(long long x,long long y,long p)
{
if(y==0) return 1%p;//任何数的0次方都是1,所以直接返回1%p
long long z=ksm(x,y/2,p);//定义一个新变量,让它等于开方后的数。这是一种二分的思想,比如本题样例:2^10=2^5*2^5=(2^2*2^2*2)*(2^2*2^2*2)......这样一直分下去,复杂度就是logn,因为每一次操作相当于开根,这样就可以大大降低复杂度。如果不用快速幂,那么就要一个一个乘下去,复杂度就是n。此题的范围是10^9,如果真的取到10^9,那么就会炸裂(计算机速度一般在3*10^8~8*10^8之间,为了保险一般只要时间复杂度在10^8以内就能保证在1s内跑出来)

z=1ll*z*z%p;//乘以1ll就相当于强制类型转化,将z从int转化为long long
if(y%2==1) z=1ll*z*x%p;//如果不能整除2,那么就要再多乘上一个x,只要乘logn次
return z;
}
long long x[1010][1010];
long long a,b,k,n,m,i,j,len;
int main()
{
cin>>a>>b>>k>>n>>m;
x[1][1]=1;//第一个数是1
for(i=2;i<=k+1;i++)
{
for(j=1;j<=i;j++)
{
len=ksm(a,n,10007)*ksm(b,m,10007)%10007//;这个就是那个系数
x[i][j]=(x[i-1][j]+x[i-1][j-1])%10007;//dp方程,我把他想象成一个矩阵,那么x[i][j]就应该等于x[i-1][j]+x[i-1][j-1],也就是左上方和上方的数的和
}
}
cout<<x[k+1][m+1]*len%10007;//找到规律再取模
return 0;
}

猜你喜欢

转载自www.cnblogs.com/57xmz/p/12820534.html
今日推荐