Description
A国是一个神奇的国家。
这个国家有
2
n
2n 个城市,每个城市都有一个独一无二的编号 ,编号范围为0~
2
n
2n-1。
A国的神奇体现在,他们有着神奇的贸易规则。
当两个城市u,v的编号满足calc(u,v)=1的时候,这两个城市才可以进行贸易(即有一条边相连)。
而calc(u,v)定义为u,v按位异或的结果的二进制表示中数字1的个数。
ex:calc(1,2)=2 ——> 01 xor 10 = 11
calc(100,101)=1 ——> 0110,0100 xor 0110,0101 = 1
calc(233,233)=0 ——> 1110,1001 xor 1110,1001 = 0
每个城市开始时都有不同的货物存储量。
而贸易的规则是:
每过一天,可以交易的城市之间就会交易一次。
在每次交易中,当前城市u中的每个货物都将使所有与当前城市u有贸易关系的城市货物量 +1 。
请问 t 天后,每个城市会有多少货物。
答案可能会很大,所以请对1e9+7取模。
Input
第一行两个正整数 n , t,意义如题。
第二行 2^n 个非负整数,第 i 个数表示编号为 i-1 的城市的初始货物存储量。
n<=20 t<=10^9
Output
输出一行 2^n 个非负整数。
第 i 个数表示过了 t 天后,编号为 i-1 的城市上的货物数量对 1e9+7 取模的结果。
Sample Input
样例1:
3 2
1 2 3 4 5 6 7 8
样例2:
1 1
0 1
Sample Output
样例1:
58 62 66 70 74 78 82 86
样例2:
1 1
题解
单考虑n比较小的情况,显然可以矩乘
n很大的情况不能矩乘了,但我们可以推出另外一个算法
对于一个值
不妨设当前货物数是
显然他一次转移是
构造一个多项式使得他只有在 位置为1
卷积一次就是下一个答案了
快速幂+ 即可
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define mod 1000000007
#define inv2 500000004
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(int x)
{
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXNLEN[22]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152};
inline void ad(int &u,int x,int y){u=x+y;if(u>=mod)u-=mod;}
inline void dl(int &u,int x,int y){u=x-y;if(u<0)u+=mod;}
inline void fwt_xor(int *y,int len,int on)
{
for(int i=1;i<len;i<<=1)
for(int j=0;j<len;j+=(i<<1))
for(int k=0;k<i;k++)
{
int u=y[j+k],v=y[j+k+i];
ad(y[j+k],u,v);dl(y[j+k+i],u,v);
// y[j+k]=(u+v)%;
// y[j+k+i]=(u-v+mod)%mod;
if(on==-1)y[j+k]=1LL*y[j+k]*inv2%mod,y[j+k+i]=1LL*y[j+k+i]*inv2%mod;
}
}
int pow_mod(int a,int b)
{
int ret=1;
while(b)
{
if(b&1)ret=1LL*ret*a%mod;
a=1LL*a*a%mod;b>>=1;
}
return ret;
}
int A[1100000],B[1100000],n,T;
int main()
{
// freopen("a.in","r",stdin);
// freopen("b.out","w",stdout);
// int tx=clock();
n=read();T=read();n=MAXNLEN[n];
for(int i=0;i<n;i++)scanf("%d",&A[i]);
B[0]=1;
for(int i=0;MAXNLEN[i]<=n;i++)B[MAXNLEN[i]]=1;
fwt_xor(A,n,1);fwt_xor(B,n,1);
for(int i=0;i<n;i++)A[i]=1LL*A[i]*pow_mod(B[i],T)%mod;
fwt_xor(A,n,-1);
// int ty=clock();pr1(ty-tx);
for(int i=0;i<n;i++)pr1(A[i]);
return 0;
}