题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773
本题解用来记录题型,题解来自(侵删):https://blog.csdn.net/zzkksunboy/article/details/79147935
题意:
有个点,每次点会使的点增加个货物,其中表示在二进制下1的个数,表示点上一次的货物数量。
问时刻之后,每个点货物的数量。
解析:
令时刻的状态为,那么根据题意得出:
怎么看都疑似异或卷积啊,转化一下:
这明显就是异或卷积的形式了,构造向量满足:
那么,快速幂一下就行了。
代码:
#include<bits/stdc++.h> using namespace std; const int MAXN = 2330010; const int MOD = 1e9 + 7; const int inv2 = 5e8 + 4; //2的逆元 int n,N,t,a[MAXN],b[MAXN]; void FWT_xor(int *a,int opt) { for(int i=1;i<N;i<<=1) for(int p=i<<1,j=0;j<N;j+=p) for(int k=0;k<i;++k) { int X=a[j+k],Y=a[i+j+k]; a[j+k]=(X+Y)%MOD;a[i+j+k]=(X+MOD-Y)%MOD; if(opt==-1)a[j+k]=1ll*a[j+k]*inv2%MOD,a[i+j+k]=1ll*a[i+j+k]*inv2%MOD; } } int inline read() { int x=0,f=1;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 pow_mod(int n,int k) { int res=1; n=n%MOD; while(k>0) { if(k&1) res=(long long)res*n%MOD; n=(long long)n*n%MOD; k>>=1; } return res; } inline void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } int main() { n=read(), t=read(); N = 1 << n; for (int i = 0; i < N; i++) { a[i]=read(); } b[0] = 1; for (int i = 0; i < n; i++) { b[1 << i] = 1; } FWT_xor(a, 1); FWT_xor(b, 1); for (int i = 0; i < N; i++) { a[i] = (long long)a[i] * pow_mod(b[i], t) % MOD; } FWT_xor(a, -1); for (int i = 0; i < N; i++) { write((a[i] + MOD) % MOD); putchar(' '); } putchar(10); return 0; }