题目
戳这里
对于每一对可以贸易的城市
u
,
v
u,v
u,v,满足
c
l
a
c
(
u
,
v
)
=
1
clac(u,v)=1
clac(u,v)=1,即满足
u
x
o
r
v
=
2
k
u~xor~v=2^k
u xor v=2k,变换一下成为
u
x
o
r
2
k
=
v
u~xor~2^k=v
u xor 2k=v,那么
u
u
u便可以给每一个
u
x
o
r
2
k
u~xor~2^k
u xor 2k做出
A
u
A_{u}
Au的贡献
那么可以构造一个数列B满足:
B
2
k
=
1
,
B
0
=
1
,
B_{2^k}=1,B_{0}=1,
B2k=1,B0=1,其余情况为
0
0
0
那么将
A
A
A用
x
o
r
xor
xor卷积卷
B
n
B~n
B n次即可得到答案
可以FWT加速。。。时间复杂度 O ( n l o g 2 T ) O(nlog_{2}T) O(nlog2T)
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<deque>
#include<algorithm>
#define maxn 2000005
#define MOD 1000000007
#define inv2 500000004
using namespace std;
inline int getint()
{
int num=0,flag=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
return num*flag;
}
int T,n;
long long ans;
bool not_prime[maxn];
int prime[maxn],cnt;
long long A[maxn];
long long a[maxn];
int rev[maxn];
inline void FWT_xor(long long *a,int inv)
{
for(int i=0;i<n;++i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int mid=1;mid<n;mid<<=1)
for(int j=0,tmp=mid<<1;j<n;j+=tmp)
for(int k=0;k<mid;++k)
{
int x=a[j+k],y=a[mid+j+k];
a[j+k]=(x+y)%MOD,a[mid+j+k]=(x+MOD-y)%MOD;
if(inv==-1)(a[j+k]*=inv2)%=MOD,(a[mid+j+k]*=inv2)%=MOD;
}
}
inline void putint(long long num)
{
if(num>9)putint(num/10);
putchar(num%10+48);
}
int main()
{
n=getint(),T=getint();
for(int i=0;i<(1<<n);++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(n-1));
for(int i=0;i<n;++i)a[1<<i]=1;a[0]=1;
n=1<<n;
for(int i=0;i<n;++i)A[i]=getint();
FWT_xor(A,1),FWT_xor(a,1);
while(T)
{
if(T&1)for(int i=0;i<n;i++)(A[i]*=a[i])%=MOD;
for(int i=0;i<n;i++)(a[i]*=a[i])%=MOD;T>>=1;
}
FWT_xor(A,-1);
for(int i=0;i<n;++i)
{
putint(A[i]);
if(i==n-1)putchar('\n');
else putchar(' ');
}
}