51NOD 1773 A国的贸易

题目

这里

对于每一对可以贸易的城市u,vu,v,满足clac(u,v)=1clac(u,v)=1,即满足u xor v=2ku~xor~v=2^k,变换一下成为
u xor 2k=vu~xor~2^k=v,那么uu便可以给每一个u xor 2ku~xor~2^k做出AuA_{u}的贡献

那么可以构造一个数列B满足:
B2k=1,B0=1,B_{2^k}=1,B_{0}=1,其余情况为00
那么将AAxorxor卷积卷B nB~n次即可得到答案

可以FWT加速。。。时间复杂度O(nlog2T)O(nlog_{2}T)

代码:

#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(' ');
	}
}
posted @ 2018-12-22 17:35  Izayoi_Doyo  阅读(189)  评论(0编辑  收藏  举报