51NOD 1773 A国的贸易
题目
戳这里
对于每一对可以贸易的城市,满足,即满足,变换一下成为
,那么便可以给每一个做出的贡献
那么可以构造一个数列B满足:
其余情况为
那么将用卷积卷次即可得到答案
可以FWT加速。。。时间复杂度
代码:
#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(' ');
}
}