嗯,序列写一写可以发现,从最后面开始相邻的差都是杨辉三角。然后走到头,前面还有剩余的话就是 2m 。啊这里说的是系数。然后我们可以求出循环节来。求出系数来之后先模循环节。循环节其实就是 ax==1modm 中的x。然后快速幂搞一下就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 107;
const int MAXN = 1e6+7;
LL n,m,a,q;
LL quick_mod(LL a,LL b,LL mod)
{
LL ans = 1,base = a%mod;
while(b)
{
if(b & 1)ans = ans*base%mod;
base = base*base%mod;
b >>= 1;
}
return ans;
}
LL num[MAXN],two[MAXN];
void init(LL mod)
{
num[1] = 1;
for(LL i = 2; i <= m; ++i)
{
num[i] = num[i-1]*i%mod;
}
two[0] = 1;
for(LL i = 1; i <= n; ++i)
{
two[i] = two[i-1]*2%mod;
}
}
LL C(LL n,LL m,LL mod)
{
LL ans = num[n];
ans = ans*quick_mod(num[m],mod-2,mod)%mod;
ans = ans*quick_mod(num[n-m],mod-2,mod)%mod;
return ans;
}
LL ans[MAXN];
int main()
{
scanf("%I64d%I64d%I64d%I64d",&n,&m,&a,&q);
LL mod = 1;
LL x = a;
for(;; mod++)
{
x %= q;
if(x == 1)break;
x *= a;
}
init(mod);
LL i;
ans[n] = 1;
for(i = n-1; i >= 1; --i)
{
LL p = n-i;
if(p == m)break;
ans[i] = (ans[i+1] + C(m,p,mod))%mod;
}
for(; i >= 1; --i)ans[i] = two[m];
//for(int i = 1; i <= n; ++i)printf("%I64d\n",ans[i]);
for(int i = 1; i <= n; ++i)
{
ans[i] = quick_mod(a,ans[i],q);
}
for(int i = 1; i <= n; ++i)printf("%I64d ",ans[i]);
return 0;
}