2018牛客网暑期ACM多校训练营(第九场)A
题解:
观察样例感觉是个卷积,然后发现是个xor的FWT。
题意转换成,给个a数组和c数组,求一个b数组,使得a数组和b数组做FWT后的结果为c数组。
然后观察FWT的过程:对a,b数组做FWT,c[i]=a[i]*b[i],然后对c数组做UFWT。
我们把这个过程倒过来:先对c数组做UFWT,然后对a数组做FWT,然后b[i]=c[i]/a[i],最后对b数组做FWT,就把b数组还原了。
观察样例感觉是个卷积,然后发现是个xor的FWT。
题意转换成,给个a数组和c数组,求一个b数组,使得a数组和b数组做FWT后的结果为c数组。
然后观察FWT的过程:对a,b数组做FWT,c[i]=a[i]*b[i],然后对c数组做UFWT。
我们把这个过程倒过来:先对c数组做UFWT,然后对a数组做FWT,然后b[i]=c[i]/a[i],最后对b数组做FWT,就把b数组还原了。
代码:
#include <bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") #define mem(a,b) memset((a),(b),sizeof(a)) #define MP make_pair #define pb push_back #define fi first #define se second #define sz(x) (int)x.size() #define all(x) x.begin(),x.end() using namespace __gnu_cxx; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; typedef vector<int> VI; typedef vector<ll> VL; void go(); int main(){ #ifdef tokitsukaze freopen("TEST.txt","r",stdin); #endif go();return 0; } const int INF=0x3f3f3f3f; const ll LLINF=0x3f3f3f3f3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-6; const int MAX=6e5+10; const ll mod=1e9+7; /********************************* head *********************************/ namespace FWT { ll inv2; const ll p=1e9+7; ll pow2(ll a,ll b) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } void fwt(ll *a,int n,int v) { for(int d=1;d<n;d<<=1) { for(int m=d<<1,i=0;i<n;i+=m) { for(int j=0;j<d;j++) { ll x=a[i+j],y=a[i+j+d]; if(!v) a[i+j]=(x+y)%p,a[i+j+d]=(x-y+p)%p; else a[i+j]=(x+y)*inv2%p,a[i+j+d]=(x-y+p)%p*inv2%p; } } } } void XOR(ll *a,ll *b,int n) { int len; for(len=1;len<=n;len<<=1); fwt(a,len,0); fwt(b,len,0); for(int i=0;i<len;i++) a[i]=a[i]*b[i]%p; inv2=pow2(2,p-2); fwt(a,len,1); } void XOR_inv(ll *a,ll *b,int n) { int len; for(len=1;len<=n;len<<=1); inv2=pow2(2,p-2); fwt(a,len,1); fwt(b,len,0); for(int i=0;i<len;i++) a[i]=a[i]*pow2(b[i]%p,p-2)%p; fwt(a,len,0); } }; ll a[MAX],b[MAX]; void go() { int n,i; while(read(n)) { for(i=0;i<n;i++) read(b[i]); for(i=0;i<n;i++) read(a[i]); FWT::XOR_inv(a,b,n); for(i=0;i<n;i++) printf("%lld\n",a[i]); } }