洛谷P1313 计算系数
题目描述
给定一个多项式(by+ax)^k,请求出多项式展开后x^n y^m项的系数。
输入格式
共一行,包含55个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。
输出格式
共1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对1000710007 取模后的结果。
输入输出样例
1 1 3 1 2
3
说明/提示
【数据范围】
对于30% 的数据,有0 ≤k ≤10;
对于50%的数据,有a = 1,b = 1;
对于100%的数据,有0≤k≤1,000,0≤n,m≤k,且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;
}