Consider an array A with N elements, all being the same integer a.
Define the product transformation as a simultaneous update Ai = Ai·Ai + 1, that is multiplying each element to the element right to it for , with the last number AN remaining the same. For example, if we start with an array A with a = 2 and N = 4, then after one product transformation A = [4, 4, 4, 2], and after two product transformations A = [16, 16, 8, 2].
Your simple task is to calculate the array A after M product transformations. Since the numbers can get quite big you should output them modulo Q.
The first and only line of input contains four integers N, M, a, Q (7 ≤ Q ≤ 109 + 123, 2 ≤ a ≤ 106 + 123, ,
is prime), where
is the multiplicative order of the integer a modulo Q, see notes for definition.
You should output the array A from left to right.
2 2 2 7
1 2
The multiplicative order of a number a modulo Q , is the smallest natural number x such that ax mod Q = 1. For example,
.
首先这道题dp[i][j]表示第i个数字进行j次的指数。
显然dp[i][j]=dp[i-1][j]+dp[i-1][j+1]。
翻转序列之后就是裸的组合数。
数据太大,我们预处理阶乘之后在线计算组合数。
最终模数暴力算。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a,q,mod,fac[1000005],inv[1000005],ans[1000005];
int pow(int a,int b,int mod)
{
int r=1;
while(b)
{
if(b&1)r=1ll*r*a%mod;
a=1ll*a*a%mod;b>>=1;
}
return r;
}
int C(int a,int b)
{
return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&a,&q);
int tmp=1;
for(int i=1;;i++)
{
tmp=1ll*tmp*a%q;
if(tmp==1)
{
mod=i;
break;
}
}
fac[0]=1;
for(int i=1;i<=m;i++) fac[i]=1ll*fac[i-1]*i%mod;
inv[m]=pow(fac[m],mod-2,mod);
for(int i=m-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
tmp=0;
for(int i=0;i<n;i++)
{
if(i<=m)tmp=(tmp+C(m,min(m,i)))%mod;
ans[n-i]=tmp;
}
for(int i=1;i<=n;i++) printf("%d ",pow(a,ans[i],q));
}